﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="Reporting.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using GenericTools;
using Microsoft.Reporting.WinForms;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using System.ComponentModel;
using DataModels.Enumerations;
using DataModels.Common;
using ReportingManagement.Components;
using GenericTools.OfflineDataCapture;
using System.Text.RegularExpressions;
using ReportingManagement.Components.Queries;

namespace ReportingManagement
{
	public partial class MainWindow
	{
		#region Class Constants
		private const string FACCODE = "FACCODE";
		private const string FACILITY_NAME = "FACILITYNAME";
		private const string DISTRICT_NAME = "DISTRICTNAME";
		private const string REGION_NAME = "REGIONNAME";
		private const string FACILITY_TYPE = "FACILITYTYPE";
		private const string PROVIDEDBS = "PROVIDEDBS";
		private const string HOSPITAL = "HOSPITAL";
		private const string DISPENSARY = "DISPENSARY";
		private const string HEALTH_CENTRE = "HEALTHCENTRE";
		private const string PMTCTSITE = "PMTCTSITE";
		private const string ANCSERVICES = "ANCSERVICES";

        private const string INTERNAL_FACILITY_NAME = "INTERNALFACILITYNAME";
        private const string INTERNAL_DISTRICT_NAME = "INTERNALDISTRICTNAME";
        private const string INTERNAL_REGION_NAME = "INTERNALREGIONNAME";

		private const int FACILITY_TYPE_HOSPITAL = 3;
		private const int FACILITY_TYPE_HEALTH_CENTRE = 2;
		private const int FACILITY_TYPE_DISPENSARY = 1;

        private const string REPORT_DETAILS_DATA_DESCRIPTION_COLUMN_NAME = "Data Description";
        private const string REPORT_DETAILS_REPORT_DATA_COLUMN_NAME = "Data";
        private const string SUBMITTED_REPORTS_COMMENTS_COLUMN_NAME = "Comments";
		#endregion

		#region Class Variables
		private string m_SelectedFilePath = null;
		private BackgroundWorker backgroundWorker = null;
		private bool completed = false;
		private bool generatingSAPR = false;
		private bool generatingSAPRPromise = false;
		private bool generatingPMTCT = false;

		int sapr_startYear = 0;
		int sapr_startPeriod = 0;
		int sapr_endYear = 0;
		int sapr_endPeriod = 0;

		bool sapr_districtsSelected = false;
		bool sapr_regionsSelected = false;
		bool sapr_nationSelected = false;

		bool sapr_useBaselineData = false;
		bool sapr_useMaximumValues = false;
		DateTime sapr_useMax_startDate = DateTime.Now;
		DateTime sapr_useMax_endDate = DateTime.Now;

		int sapr_districtID = 0;
		int sapr_regionID = 0;

		int pmtct_startYear = 0;
		int pmtct_startPeriod = 0;
		int pmtct_endYear = 0;
		int pmtct_endPeriod = 0;

		bool pmtct_districtsSelected = false;
		bool pmtct_regionsSelected = false;
		bool pmtct_nationSelected = false;

		int pmtct_districtID = 0;
		int pmtct_regionID = 0;

		bool operationCanceled = false;
		bool operationSucceeded = false;

        /// <summary>
        /// Holds the index of the facility for loading data.
        /// </summary>
		#endregion

		struct SAPRProgress
		{
			public string log;
			public int minValue;
			public int maxValue;
			public int value;
		}

		#region Basic Reports Tab page
		private bool tabPageBasicReportsLoaded = false;
		private bool monthlySummaryFormat = false;
		private DataTable reportDetails = null;
		private DataTable submittedReports = null;
		private DataTable missingReports = null;
		private DataTable reportDataCount = null;

		private void tabPageBasicReports_Enter(object sender, EventArgs e)
		{
			if (!tabPageBasicReportsLoaded)
			{
                // Set up event handler for the embeded user control in this tab
                var customReports = elementHostCustomReports.Child as CustomReports;
                if (customReports != null)
                {
                    customReports.StatusChanged += ToolStripStatusLabel_StatusChanged;
                }

				try
				{
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					DataTable dataTable = Utilities.GetAllExpectedReportViews();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cbReportType.Items.Clear();
					foreach (DataRow row in dataTable.Rows)
					{
						ListItem item = new ListItem();
						item.Text = row["ReportName"].ToString();
						item.Value = row["RepID"];
						cbReportType.Items.Add(item);
					}
					try
					{
						cbReportType.SelectedIndex = 0;
					}
					catch { }

					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					dataTable = Utilities.GetAllReportYears();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string year = row["Year"].ToString();
						cbYear.Items.Add(year);
						cbToYear.Items.Add(year);
					}

					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					dataTable = Utilities.GetAllReportPeriods();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string period = row["Period"].ToString();
						cbPeriod.Items.Add(period);
						cbToPeriod.Items.Add(period);
					}
					try
					{
						cbYear.SelectedIndex = 0;
						cbToYear.SelectedIndex = 0;
						cbPeriod.SelectedIndex = 0;
						cbToPeriod.SelectedIndex = 0;
					}
					catch { }
					btnGetReport.Enabled = false;

					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.FACILITY:
							rdDistrict.Enabled = false;
							rdRegion.Enabled = false;
							rdNational.Enabled = false;
							break;

                        case AccessLevel.DISTRICT:
							rdRegion.Enabled = false;
							rdNational.Enabled = false;
							break;

                        case AccessLevel.REGION:
							rdNational.Enabled = false;
							break;
					}
					tabPageBasicReportsLoaded = true;
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdSite_CheckedChanged(object sender, EventArgs e)
		{
			if (rdSite.Checked)
			{
				try
				{
					lblName.Text = "Facility Name:";
					DataTable dataTable = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.FACILITY:
							string facilityCode = this.authenticatedUser.AccessLevelValue;
							dataTable = Utilities.GetFacilityDetails(facilityCode);
							break;

                        case AccessLevel.DISTRICT:
							int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID);
							break;

                        case AccessLevel.REGION:
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetFacilitiesDetailsByRegion(regionID, this.authenticatedUser.SupportingPartnerId);
							break;

                        case AccessLevel.NATION:
							dataTable = Utilities.GetAllFacilitiesStatus(this.authenticatedUser.SupportingPartnerId);
							break;

						default:
							//dataTable = Utilities.GetAllFacilities();
							dataTable = Utilities.GetAllFacilitiesStatus();
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cbName.DataSource = null;
					//cbName.ValueMember = "FacCode";
					//cbName.DisplayMember = "FacName";
					cbName.ValueMember = dataTable.Columns[0].ColumnName;
					cbName.DisplayMember = dataTable.Columns[1].ColumnName;

					cbName.DataSource = dataTable;
					UpdateGovFormatButton();
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdDistrict_CheckedChanged(object sender, EventArgs e)
		{
			if (rdDistrict.Checked)
			{
				try
				{
					lblName.Text = "District Name:";
					DataTable dataTable = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.DISTRICT:
							int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetDistrict(districtID);
							break;

                        case AccessLevel.REGION:
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetDistrictsByRegion(regionID, this.authenticatedUser.SupportingPartnerId);
							break;

                        case AccessLevel.NATION:
							dataTable = Utilities.GetAllDistricts(this.authenticatedUser.SupportingPartnerId);
							break;

						default:
							dataTable = Utilities.GetAllDistricts();
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cbName.DataSource = null;
					cbName.ValueMember = "DistrictNo";
					cbName.DisplayMember = "District";
					cbName.DataSource = dataTable;
					UpdateGovFormatButton();
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdRegion_CheckedChanged(object sender, EventArgs e)
		{
			if (rdRegion.Checked)
			{
				try
				{
					lblName.Text = "Region Name:";
					DataTable dataTable = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.REGION:
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetRegion(regionID);
							break;

                        case AccessLevel.NATION:
							dataTable = Utilities.GetAllRegions(this.authenticatedUser.SupportingPartnerId);
							break;

						default:
							dataTable = Utilities.GetAllRegions();
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cbName.DataSource = null;
					cbName.ValueMember = "RegionID";
					cbName.DisplayMember = "RegionName";
					cbName.DataSource = dataTable;
					UpdateGovFormatButton();
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdNational_CheckedChanged(object sender, EventArgs e)
		{
			if (rdNational.Checked)
			{
				lblName.Enabled = false;
				cbName.Enabled = false;
				btnGetReport.Enabled = true;
			}
			else
			{
				lblName.Enabled = true;
				cbName.Enabled = true;
			}
		}

		private void btnGetReport_Click(object sender, EventArgs e)
		{
			#region Preliminary Checks
			int startYear = Int32.Parse(cbYear.Text);
			int endYear = Int32.Parse(cbToYear.Text);
			int startPeriod = Int32.Parse(cbPeriod.Text);
			int endPeriod = Int32.Parse(cbToPeriod.Text);
			ListItem item = (ListItem)cbReportType.SelectedItem;
			int reportID = Int32.Parse(item.Value.ToString());

			if (startYear >= endYear)
			{
				if (startYear > endYear)
				{
					MessageBox.Show(this,
						"Invalid timeframe! Starting year should be less than or equal to Ending year",
						AppConfiguration.ApplicationName,
						MessageBoxButtons.OK, MessageBoxIcon.Warning);
					return;
				}
				else
				{
					if (startPeriod > endPeriod)
					{
						MessageBox.Show(this,
						"Invalid timeframe! Starting period should be less than or equal to Ending period",
						AppConfiguration.ApplicationName,
						MessageBoxButtons.OK, MessageBoxIcon.Warning);
						return;
					}
				}
			}

			lblSubmitted.Visible = false;
			lblSubmittedBy.Visible = false;
			lblSubmitDate.Visible = false;
			lblDateSubmitted.Visible = false;
			lblMissingReports.Visible = false;
            lklChangeThisReport.Visible = false;
			#endregion

			try
			{
				Cursor.Current = Cursors.WaitCursor;
				btnGetReport.Enabled = false;
				tbReportDetails.Enabled = false;
				toolStripStatusLabel.Text = "Loading data, please wait...";
				Application.DoEvents();

                AccessLevel requestLevel = AccessLevel.RESTRICTED;
                string requestValue = string.Empty;
                if (rdSite.Checked)
                {
                    requestLevel = AccessLevel.FACILITY;
                    requestValue = cbName.SelectedValue.ToString();
                }

                if (rdDistrict.Checked)
                {
                    requestLevel = AccessLevel.DISTRICT;
                    requestValue = cbName.SelectedValue.ToString();
                }

                if (rdRegion.Checked)
                {
                    requestLevel = AccessLevel.REGION;
                    requestValue = cbName.SelectedValue.ToString();
                }

                if (rdNational.Checked) requestLevel = AccessLevel.NATION;

                DataSet reportingInfo = Utilities.GetReportingInfo(
                    requestLevel, requestValue,                    
                    reportID, startYear, startPeriod, endYear, endPeriod,
                    this.authenticatedUser.Level, this.authenticatedUser.SupportingPartnerId);

                DataTable detailsTable = reportingInfo.Tables[Utilities.DETAILS_TABLE_NAME];
                DataTable dataCountTable = reportingInfo.Tables[Utilities.DATA_COUNT_TABLE_NAME];
                DataTable submissionTable = reportingInfo.Tables[Utilities.SUBMITTED_TABLE_NAME];
                DataTable missingTable = reportingInfo.Tables[Utilities.MISSING_TABLE_NAME];

                dgvRepDetails.DataSource = detailsTable;
                dgvDataCounts.DataSource = dataCountTable;
                dgvSubmittedReports.DataSource = submissionTable;
                gvExceptions.DataSource = missingTable;


                this.reportDetails = detailsTable;
                this.reportDataCount = dataCountTable;
                this.submittedReports = submissionTable;
                this.missingReports = missingTable;

                if (rdSite.Checked)
                {
                    if ((startYear == endYear) && (startPeriod == endPeriod) && (missingTable.Rows.Count == 0))
                    {
                        lblSubmitted.Visible = true;
                        lblSubmittedBy.Visible = true;
                        lblSubmitDate.Visible = true;
                        lblDateSubmitted.Visible = true;

                        bool canChangeThisReport = false;
                        if (tabMain.TabPages.Contains(tabPageDataCapture))
                        {
                            if (this.submittedReports.Rows.Count == 1 && this.missingReports.Rows.Count == 0)
                            {
                                if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS)
                                    || (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
                                {
                                    bool offlineDataCapturingInitialized = OfflineDataCapturing.InitializeOfflineDataSavingEnvironment();
                                    canChangeThisReport = offlineDataCapturingInitialized;
                                }
                                else
                                {
                                    canChangeThisReport = true;
                                }
                            }
                        }

                        lklChangeThisReport.Visible = true;
                        lklChangeThisReport.Enabled = canChangeThisReport;


                        DataTable submissionInfoTable = reportingInfo.Tables[Utilities.SUBMISSION_INFO_TABLE_NAME];
                        string name = String.Empty;
                        DateTime? dateReceived = null;
                        try
                        {
                            dateReceived = DateTime.Parse(submissionInfoTable.Rows[0]["DateReceived"].ToString());
                            name = submissionInfoTable.Rows[0]["Name"].ToString();
                            if (String.IsNullOrEmpty(name)) name = submissionInfoTable.Rows[0]["SenderNum"].ToString();
                            else
                            {
                                string phone = submissionInfoTable.Rows[0]["SenderNum"].ToString();
                                name = String.Format("{0} [{1}]", name, phone);
                            }
                        }
                        catch
                        {
                            try
                            {
                                name = submissionInfoTable.Rows[0]["SenderNum"].ToString();
                            }
                            catch { }
                        }

                        lblSubmittedBy.Text = name;
                        lblDateSubmitted.Text = dateReceived.ToString();
                    }
                }

				#region Updating UI Accordingly
				dgvRepDetails.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
				dgvRepDetails.Columns[0].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
				dgvRepDetails.Columns[0].ReadOnly = true;

				dgvSubmittedReports.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

				gvExceptions.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
				if (gvExceptions.Rows.Count > 0)
				{
					int count = gvExceptions.Rows.Count;
					string template = String.Empty;
					template = (count > 1) ? "There are {0} missing reports" : "There is {0} missing report";
					lblMissingReports.Text = String.Format(template, count);
					lblMissingReports.Visible = true;
				}

				if (this.reportDetails.Rows.Count > 0)
				{
					btnExportReportDetails.Enabled = true;
					btnExportGovFormat.Enabled = true;
				}
				else
				{
					btnExportReportDetails.Enabled = false;
					btnExportGovFormat.Enabled = false;
				}

				if (this.submittedReports.Rows.Count > 0) btnExportSubmittedReports.Enabled = true;
				else btnExportSubmittedReports.Enabled = false;

				if (this.missingReports.Rows.Count > 0) btnExportMissingReports.Enabled = true;
				else btnExportMissingReports.Enabled = false;

				int present = 0;
				foreach (DataRow row in this.reportDataCount.Rows) present += Int32.Parse(row[2].ToString());
				int missing = this.missingReports.Rows.Count;
				int expected = present + missing;

				lblExpectedReportsCount.Text = expected.ToString();
				lblMissingReportCount.Text = missing.ToString();
				lblPresentReportCount.Text = present.ToString();
				#endregion

				tbReportDetails.Enabled = true;
				btnGetReport.Enabled = true;
				Cursor.Current = Cursors.Default;
				toolStripStatusLabel.Text = "Ready";
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
				tbReportDetails.Enabled = true;
				btnGetReport.Enabled = true;
				return;
			}
		}

		private void btnExportGovFormat_Click(object sender, EventArgs e)
		{
			int startYear = Int32.Parse(cbYear.Text);
			int endYear = Int32.Parse(cbToYear.Text);
			int startPeriod = Int32.Parse(cbPeriod.Text);
			int endPeriod = Int32.Parse(cbToPeriod.Text);
			ListItem item = (ListItem)cbReportType.SelectedItem;
			int reportID = Int32.Parse(item.Value.ToString());

			try
			{
				DataSet dataset = new DataSet();
				string facilityCode = cbName.SelectedValue.ToString();

				Cursor.Current = Cursors.WaitCursor;
				btnExportGovFormat.Enabled = false;
				toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
				Report report = null;

				if (rdSite.Checked)
				{
					DataTable dataTable = Utilities.GetFacilityReport(facilityCode, reportID, startYear,
						startPeriod, endYear, endPeriod);
					dataset.Tables.Add(dataTable.Copy());

					if (monthlySummaryFormat)
					{
						report = new Report(ReportTypes.MONTHLY_SUMMARY_FORM, ReportLevel.FACILITY,
							String.Empty, DateTime.Now, DateTime.Now);
						ReportParameter[] parameters = CreateReportParameters();
						report.SetParameters(parameters);
						report.SetDataSet(dataset);
					}
					else
					{
						report = new Report(ReportTypes.MONTHLY_SUMMARY_FORM, ReportLevel.NATION,
							String.Empty, DateTime.Now, DateTime.Now);
						ReportParameter[] parameters = CreateAggregateSummaryFormReportParameters();
						report.SetParameters(parameters);
						report.SetDataSet(dataset);
					}
				}

				if (rdDistrict.Checked)
				{
					int districtID = Int32.Parse(cbName.SelectedValue.ToString());
					DataTable dataTable = Utilities.GetDistrictReport(districtID, reportID, startYear,
						startPeriod, endYear, endPeriod);
					dataset.Tables.Add(dataTable.Copy());
					report = new Report(ReportTypes.MONTHLY_SUMMARY_FORM, ReportLevel.DISTRICT,
							String.Empty, DateTime.Now, DateTime.Now);
					ReportParameter[] parameters = CreateAggregateSummaryFormReportParameters();
					report.SetParameters(parameters);
					report.SetDataSet(dataset);
				}

				if (rdRegion.Checked)
				{
					int regionID = Int32.Parse(cbName.SelectedValue.ToString());
					DataTable dataTable = Utilities.GetRegionReport(regionID, reportID, startYear,
						startPeriod, endYear, endPeriod);
					dataset.Tables.Add(dataTable.Copy());
					report = new Report(ReportTypes.MONTHLY_SUMMARY_FORM, ReportLevel.REGION,
							String.Empty, DateTime.Now, DateTime.Now);
					ReportParameter[] parameters = CreateAggregateSummaryFormReportParameters();
					report.SetParameters(parameters);
					report.SetDataSet(dataset);
				}

				if (rdNational.Checked)
				{
					DataTable dataTable = Utilities.GetNationReport(reportID, startYear,
						startPeriod, endYear, endPeriod);
					dataset.Tables.Add(dataTable.Copy());
					report = new Report(ReportTypes.MONTHLY_SUMMARY_FORM, ReportLevel.NATION,
							String.Empty, DateTime.Now, DateTime.Now);
					ReportParameter[] parameters = CreateAggregateSummaryFormReportParameters();
					report.SetParameters(parameters);
					report.SetDataSet(dataset);
				}

				btnExportGovFormat.Enabled = true;
				Cursor.Current = Cursors.Default;
				toolStripStatusLabel.Text = "Ready";

				report.ShowDialog(this);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
				btnExportGovFormat.Enabled = true;
			}
		}

		private ReportParameter[] CreateReportParameters()
		{
			string title = cbReportType.Text;
			string facilityName = cbName.Text;
			string facilityCode = cbName.SelectedValue.ToString();
			string month = Utilities.GetMonthText(Int32.Parse(cbPeriod.Text));
			string year = cbYear.Text;

			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			string districtName = Utilities.GetFacilityDistrict(facilityCode).Rows[0]["District"].ToString();
			string regionName = Utilities.GetFacilityRegion(facilityCode).Rows[0]["RegionName"].ToString();
			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			ReportParameter[] parameters = new ReportParameter[7];
			parameters[0] = new ReportParameter("ReportTitle", title);
			parameters[1] = new ReportParameter("FacilityName", facilityName);
			parameters[2] = new ReportParameter("FacilityCode", facilityCode);
			parameters[3] = new ReportParameter("DistrictName", districtName);
			parameters[4] = new ReportParameter("RegionName", regionName);
			parameters[5] = new ReportParameter("ReportMonth", month);
			parameters[6] = new ReportParameter("ReportYear", year);
			return parameters;
		}

		private ReportParameter[] CreateAggregateSummaryFormReportParameters()
		{
			string title = cbReportType.Text;
			string facilityName = "All Registered Facilities in the Country";
			string startMonth = Utilities.GetMonthText(Int32.Parse(cbPeriod.Text));
			string endMonth = Utilities.GetMonthText(Int32.Parse(cbToPeriod.Text));

			string startYear = cbYear.Text;
			string endYear = cbToYear.Text;
			string timeFrame = string.Format("Report Time Scope: {0} {1} - {2} {3}", startMonth, startYear, endMonth, endYear);

			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			string districtName = "All Registered Districts";
			string regionName = "All Registered Regions";
			if (rdSite.Checked)
			{
				facilityName = cbName.Text;
				string facilityCode = cbName.SelectedValue.ToString();
				districtName = Utilities.GetFacilityDistrict(facilityCode).Rows[0]["District"].ToString();
				regionName = Utilities.GetFacilityRegion(facilityCode).Rows[0]["RegionName"].ToString();
			}

			if (rdDistrict.Checked)
			{
				facilityName = cbName.Text;
				districtName = cbName.Text;
				int districtID = Int32.Parse(cbName.SelectedValue.ToString());
				regionName = Utilities.GetDistrictRegion(districtID).Rows[0]["RegionName"].ToString();
			}

			if (rdRegion.Checked)
			{
				facilityName = cbName.Text;
				regionName = cbName.Text;
			}

			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			districtName = String.Format("District Name: {0}", districtName);
			regionName = String.Format("Region Name: {0}", regionName);

			ReportParameter[] parameters = new ReportParameter[5];
			parameters[0] = new ReportParameter("ReportTitle", title);
			parameters[1] = new ReportParameter("FacilityName", facilityName);
			parameters[2] = new ReportParameter("ReportTimeFrame", timeFrame);
			parameters[3] = new ReportParameter("DistrictName", districtName);
			parameters[4] = new ReportParameter("RegionName", regionName);
			return parameters;
		}

		private void UpdateGovFormatButton()
		{
			btnGetReport.Enabled = (cbName.Items.Count > 0);
			if (rdSite.Checked)
			{
				if (cbYear.Text == cbToYear.Text)
				{
					if (cbPeriod.Text == cbToPeriod.Text) monthlySummaryFormat = true;
					else monthlySummaryFormat = false;
				}
				else monthlySummaryFormat = false;
			}
			else monthlySummaryFormat = false;
		}

		private void cbYear_SelectedIndexChanged(object sender, EventArgs e)
		{
			UpdateGovFormatButton();
		}

		private void cbPeriod_SelectedIndexChanged(object sender, EventArgs e)
		{
			UpdateGovFormatButton();
		}

		private void cbToYear_SelectedIndexChanged(object sender, EventArgs e)
		{
			UpdateGovFormatButton();
		}

		private void cbToPeriod_SelectedIndexChanged(object sender, EventArgs e)
		{
			UpdateGovFormatButton();
		}

		private void btnExportReportDetails_Click(object sender, EventArgs e)
		{
			CreateExcelExportFile(this.reportDetails);
		}

		private void btnExportSubmittedReports_Click(object sender, EventArgs e)
		{
			CreateExcelExportFile(this.submittedReports);
			//DialogResult response = saveFileDialog.ShowDialog(this);
			//if (response == System.Windows.Forms.DialogResult.OK)
			//{
			//    try
			//    {
			//        string filename = saveFileDialog.FileName;
			//        exportingRadGridView.DataSource = this.submittedReports;
			//        exportingRadGridView.Refresh();
			//        ExportToExcelML exporter = new ExportToExcelML(exportingRadGridView);
			//        exporter.SheetName = "Submitted Reports";
			//        exporter.RunExport(filename);
			//        exporter = null;
			//        MessageBox.Show(this,
			//            "Data Export completed successfully",
			//            AppConfiguration.ApplicationName,
			//            MessageBoxButtons.OK, MessageBoxIcon.Information);
			//        return;
			//    }
			//    catch (Exception ex)
			//    {
			//        MessageBox.Show(this, ex.Message, AppConfiguration.ApplicationName,
			//            MessageBoxButtons.OK, MessageBoxIcon.Error);
			//        return;
			//    }
			//}
		}

		private void btnExportMissingReports_Click(object sender, EventArgs e)
		{
			CreateExcelExportFile(this.missingReports);
			//DialogResult response = saveFileDialog.ShowDialog(this);
			//if (response == System.Windows.Forms.DialogResult.OK)
			//{
			//    try
			//    {
			//        string filename = saveFileDialog.FileName;
			//        exportingRadGridView.DataSource = this.missingReports;
			//        exportingRadGridView.Refresh();
			//        ExportToExcelML exporter = new ExportToExcelML(exportingRadGridView);
			//        exporter.SheetName = "Missing Reports";
			//        exporter.RunExport(filename);
			//        exporter = null;
			//        MessageBox.Show(this,
			//            "Data Export completed successfully",
			//            AppConfiguration.ApplicationName,
			//            MessageBoxButtons.OK, MessageBoxIcon.Information);
			//        return;
			//    }
			//    catch (Exception ex)
			//    {
			//        MessageBox.Show(this, ex.Message, AppConfiguration.ApplicationName,
			//            MessageBoxButtons.OK, MessageBoxIcon.Error);
			//        return;
			//    }
			//}
		}

        private void lklChangeThisReport_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            lklChangeThisReport.Enabled = false;
            Application.DoEvents();

            ListItem item = cbReportType.SelectedItem as ListItem;
            if (item != null)
            {
                int reportId = int.Parse(item.Value.ToString());
                string facilityCode = cbName.SelectedValue.ToString();
                int year = int.Parse(cbYear.Text);
                int month = int.Parse(cbPeriod.Text);

                this.Cursor = Cursors.WaitCursor;
                DataTable dataTable = Utilities.GetFacilityDistrict(facilityCode);
                int districtId = int.Parse(dataTable.Rows[0]["DistrictNo"].ToString());

                dataTable = Utilities.GetFacilityRegion(facilityCode);
                int regionId = int.Parse(dataTable.Rows[0]["RegionID"].ToString());

                DataTable reportData = this.reportDetails.Copy();

                tabControlDataCapture.SelectedTab = tabPageDataCaptureNormalForms;
                tabMain.SelectedTab = tabPageDataCapture;
                bool reportSelected = SelectDataCaptureReport(reportId);
                if (!reportSelected) // Probably reporting tab uses more report while data captures uses summaried view
                {
                    btnReportSizeDataCapture.PerformClick();
                    if (!SelectDataCaptureReport(reportId)) return;
                }

                cbDIRepType.SelectedValue = reportId;
                cboRegionsForData.SelectedValue = regionId;
                cboDistrictsForData.SelectedValue = districtId;
                cbDCFacCode.SelectedValue = facilityCode;

                dgvDIRepDetails.Rows[DATA_CAPTURE_MONTH_ROW_INDEX].Cells[DATA_CAPTURE_DATA_COLUMN_NAME].Value = month;
                dgvDIRepDetails.Rows[DATA_CAPTURE_YEAR_ROW_INDEX].Cells[DATA_CAPTURE_DATA_COLUMN_NAME].Value = year;
                for (int i = DATA_CAPTURE_FIRST_INDICATOR_ROW_INDEX; i < dgvDIRepDetails.Rows.Count; i++)
                {
                    string description = dgvDIRepDetails.Rows[i].Cells[DATA_CAPTURE_DESCRIPTION_COLUMN_NAME].Value.ToString();
                    foreach (DataRow row in reportData.Rows)
                    {
                        string dataDescription = row[REPORT_DETAILS_DATA_DESCRIPTION_COLUMN_NAME].ToString();
                        if (description == dataDescription)
                        {
                            string sData = row[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ToString();
                            int data = int.Parse(sData);
                            dgvDIRepDetails.Rows[i].Cells[DATA_CAPTURE_DATA_COLUMN_NAME].Value = data;
                            reportData.Rows.Remove(row);
                            break;
                        }
                    }
                }

                // Showing the report comments
                if (submittedReports.Rows.Count == 1)
                {
                    var row = submittedReports.Rows[0];
                    txtComment.Text = row[SUBMITTED_REPORTS_COMMENTS_COLUMN_NAME].ToString();
                }

                this.Cursor = Cursors.Default;
            }
            lklChangeThisReport.Enabled = true;
        }

        private bool SelectDataCaptureReport(int toBeSelectedReportId)
        {
            bool reportSelected = false;
            foreach (var reportItem in cbDIRepType.Items)
            {
                ListItem i = reportItem as ListItem;
                if (i != null)
                {
                    int report = int.Parse(i.Value.ToString());
                    if (report == toBeSelectedReportId)
                    {
                        cbDIRepType.SelectedItem = reportItem;
                        reportSelected = true;
                        break;
                    }
                }
            }
            return reportSelected;
        }

        private void btnReportSizeBasicReports_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
            cbReportType.Enabled = false;
            btnReportSizeBasicReports.Enabled = false;
            DataTable dataTable = null;
            Application.DoEvents();

            try
            {
                if (btnReportSizeBasicReports.Text == "More...")
                {
                    dataTable = Utilities.GetAllExpectedReports();
                    btnReportSizeBasicReports.Text = "Less...";
                }
                else
                {
                    dataTable = Utilities.GetAllExpectedReportViews();
                    btnReportSizeBasicReports.Text = "More...";
                }

                cbReportType.Items.Clear();
                foreach (DataRow row in dataTable.Rows)
                {
                    ListItem item = new ListItem();
                    item.Text = row["ReportName"].ToString();
                    item.Value = row["RepID"];
                    cbReportType.Items.Add(item);
                }
                if (cbReportType.Items.Count > 0) cbReportType.SelectedIndex = 0;
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
            finally
            {
                cbReportType.Enabled = true;
                btnReportSizeBasicReports.Enabled = true;
                toolStripStatusLabel.Text = "Ready";
                Cursor.Current = Cursors.Default;
            }
        }

        
		#endregion

		#region Donor Report Tab Page
		private bool tabPageDonorReportLoaded = false;

		private void tabPageDonorReport_Enter(object sender, EventArgs e)
		{
			if (!tabPageDonorReportLoaded)
			{
				try
				{
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					DataTable dataTable = Utilities.GetAllReportYears();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string year = row["Year"].ToString();
						cboStartYear.Items.Add(year);
						cboEndYear.Items.Add(year);
					}

					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					dataTable = Utilities.GetAllReportPeriods();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string period = row["Period"].ToString();
						cboStartPeriod.Items.Add(period);
						cboEndPeriod.Items.Add(period);
					}
					try
					{
						cboStartYear.SelectedIndex = 0;
						cboEndYear.SelectedIndex = 0;
						cboStartPeriod.SelectedIndex = 0;
						cboEndPeriod.SelectedIndex = 0;
					}
					catch { }

					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.DISTRICT:
							rdoRegion.Enabled = false;
							rdoNation.Enabled = false;
							btnGenerateSAPRPromise.Visible = false;
							break;

                        case AccessLevel.REGION:
							rdoNation.Enabled = false;
							btnGenerateSAPRPromise.Visible = false;
							break;

                        case AccessLevel.NATION:
							btnGenerateSAPRPromise.Visible = false;
							break;
					}
					rdoDistrict_CheckedChanged(null, null);

					tabPageDonorReportLoaded = true;
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdoDistrict_CheckedChanged(object sender, EventArgs e)
		{
			if (rdoDistrict.Checked)
			{
				try
				{
					lblAggregation.Text = "District Name:";
					DataTable dataTable = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.DISTRICT:
							int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetDistrict(districtID);
							break;

                        case AccessLevel.REGION:
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetDistrictsByRegion(regionID, this.authenticatedUser.SupportingPartnerId);
							break;

                        case AccessLevel.NATION:
							dataTable = Utilities.GetAllDistricts(this.authenticatedUser.SupportingPartnerId);
							break;

						default:
							dataTable = Utilities.GetAllDistricts();
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cboAggregation.DataSource = null;
					cboAggregation.ValueMember = "DistrictNo";
					cboAggregation.DisplayMember = "District";
					cboAggregation.DataSource = dataTable;
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdoRegion_CheckedChanged(object sender, EventArgs e)
		{
			if (rdoRegion.Checked)
			{
				try
				{
					lblAggregation.Text = "Region Name:";
					DataTable dataTable = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.REGION:
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							dataTable = Utilities.GetRegion(regionID);
							break;

                        case AccessLevel.NATION:
							dataTable = Utilities.GetAllRegions(this.authenticatedUser.SupportingPartnerId);
							break;

						default:
							dataTable = Utilities.GetAllRegions();
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					cboAggregation.DataSource = null;
					cboAggregation.ValueMember = "RegionID";
					cboAggregation.DisplayMember = "RegionName";
					cboAggregation.DataSource = dataTable;
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		private void rdoNation_CheckedChanged(object sender, EventArgs e)
		{
			if (rdoNation.Checked)
			{
				lblAggregation.Enabled = false;
				cboAggregation.Enabled = false;
			}
			else
			{
				lblAggregation.Enabled = true;
				cboAggregation.Enabled = true;
			}
		}

		private void btnGenerateDonorReport_Click(object sender, EventArgs e)
		{
			try
			{
				Cursor.Current = Cursors.WaitCursor;
				btnGenerateDonorReport.Enabled = false;
				toolStripStatusLabel.Text = "Loading data, please wait...";
				Application.DoEvents();

				ReportLevel level = ReportLevel.FACILITY;
				int id = Int32.Parse(cboAggregation.SelectedValue.ToString());

				if (rdoDistrict.Checked) level = ReportLevel.DISTRICT;
				if (rdoRegion.Checked) level = ReportLevel.REGION;
				if (rdoNation.Checked) level = ReportLevel.NATION;

				int startYear = Int32.Parse(cboStartYear.Text);
				int endYear = Int32.Parse(cboEndYear.Text);
				int startPeriod = Int32.Parse(cboStartPeriod.Text);
				int endPeriod = Int32.Parse(cboEndPeriod.Text);

				string code = id.ToString();
				DateTime startTime = DateTime.Parse(String.Format("{0}-{1}-1", startYear, startPeriod));
				DateTime endTime = DateTime.Parse(String.Format("{0}-{1}-1", endYear, endPeriod));
				Report report = new Report(ReportTypes.DONOR_REPORT, level, code, startTime, endTime);

				toolStripStatusLabel.Text = "Ready";
				btnGenerateDonorReport.Enabled = true;
				Cursor.Current = Cursors.Default;

				report.ShowDialog(this);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
				btnGenerateDonorReport.Enabled = true;
			}
		}
		#endregion

		#region SAPR / APR and Monthly PMTCT Report
		private bool GenerateSAPR()
		{
			const int TEMPLATE_ID = 1;
			const string SUMMARY_SHEET = "Summary";
			const string DATA_SHEET = "Data";

			const int ANC_REPORT_ID = 6;
			const int PCR_REPORT_ID = 8;
			const int MAT_REPORT_ID = 7;
			const int MC_REPORT_ID = 9;

			int progress = -1;
			//string log = String.Empty;
			object misValue = System.Reflection.Missing.Value;
			completed = false;

			Excel.Application excelApplication = null;
			Excel.Workbooks excelWorkbooks = null;
			Excel.Workbook excelWorkbook = null;
			Excel.Sheets excelSheets = null;
			Excel.Worksheet excelWorksheet = null;
			try
			{
				//ExcelTemplateReport report = new ExcelTemplateReport(TEMPLATE_ID);
                ExcelTemplateReport report = (from et in PromisTemplateSelector.ExcelTemplateReports
                                              where et.TemplateID == TEMPLATE_ID
                                              select et).FirstOrDefault();
				string templatePath = String.Format(@"{0}\Resources\{1}", Application.StartupPath, report.Filename);
				System.IO.File.Delete(m_SelectedFilePath);
				System.IO.File.Copy(templatePath, m_SelectedFilePath);

				excelApplication = new Excel.Application();
				excelWorkbooks = excelApplication.Workbooks;
				excelWorkbook = excelWorkbooks.Open(m_SelectedFilePath, 0, false, 5,
					"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

				int currentSheetIndex = 1;
				excelSheets = excelWorkbook.Worksheets;
				excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheetIndex);     // 1-based index

				SAPRProgress progressInfo = new SAPRProgress();

				#region Get all facilities in particular district, district or nation
				DataTable facilitiesDetails = null;
				DataSet summaryDataSet = new DataSet();

				progressInfo.log = "Retrieving records from database. Please wait...";
				progressInfo.value = -1;
				backgroundWorker.ReportProgress(progress, progressInfo);

				if (sapr_districtsSelected)
				{
					#region Retrieving Facilities Data
					int districtID = sapr_districtID;
					progressInfo.log = "Retrieving list of facilities. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR || this.authenticatedUser.Level == AccessLevel.DISTRICT)
					{
						facilitiesDetails = Utilities.GetFacilitiesDetailsByDistrict(districtID, true);
					}
					else
					{
						facilitiesDetails = Utilities.GetFacilitiesDetailsByDistrict(districtID, this.authenticatedUser.SupportingPartnerId, true);
					}

					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities ANC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataTable summaryData = null;
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR || this.authenticatedUser.Level == AccessLevel.DISTRICT)
					{
						summaryData = Utilities.GetDistrictReport(districtID,
							ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetDistrictReport(districtID, ANC_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.ANC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities PCR reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR || this.authenticatedUser.Level == AccessLevel.DISTRICT)
					{
						summaryData = Utilities.GetDistrictReport(districtID, PCR_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetDistrictReport(districtID, PCR_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.PCR_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MAT reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR || this.authenticatedUser.Level == AccessLevel.DISTRICT)
					{
						summaryData = Utilities.GetDistrictReport(districtID, MAT_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetDistrictReport(districtID, MAT_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MAT_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR || this.authenticatedUser.Level == AccessLevel.DISTRICT)
					{
						summaryData = Utilities.GetDistrictReport(districtID, MC_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetDistrictReport(districtID, MC_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion
				}

				if (sapr_regionsSelected)
				{
					#region Retrieving Districts Data
					int regionID = sapr_regionID;
					progressInfo.log = "Retrieving list of facilities. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						facilitiesDetails = Utilities.GetFacilitiesDetailsByRegion(regionID, true);
					}
					else
					{
						facilitiesDetails = Utilities.GetFacilitiesDetailsByRegion(regionID, this.authenticatedUser.SupportingPartnerId, true);
					}
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities ANC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataTable summaryData = null;
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetRegionReport(regionID,
							ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetRegionReport(regionID, ANC_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.ANC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities PCR reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetRegionReport(regionID, PCR_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetRegionReport(regionID, PCR_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.PCR_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MAT reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetRegionReport(regionID, MAT_REPORT_ID,
						   sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetRegionReport(regionID, MAT_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MAT_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetRegionReport(regionID, MC_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetRegionReport(regionID, MC_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion
				}

				if (sapr_nationSelected)
				{
					#region Retrieving Nation Data
					progressInfo.log = "Retrieving list of facilities. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						facilitiesDetails = Utilities.GetAllFacilitiesDetails(true, true);
					}
					else
					{
						facilitiesDetails = Utilities.GetAllFacilitiesDetails(this.authenticatedUser.SupportingPartnerId, true, true);
					}
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities ANC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataTable summaryData = null;
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetNationReport(
						   ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetNationReport(ANC_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.ANC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities PCR reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetNationReport(PCR_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetNationReport(PCR_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.PCR_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MAT reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetNationReport(MAT_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetNationReport(MAT_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MAT_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progressInfo.log = "Retrieving facilities MC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
					{
						summaryData = Utilities.GetNationReport(MC_REPORT_ID,
							sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					}
					else
					{
						summaryData = Utilities.GetNationReport(MC_REPORT_ID, sapr_startYear, sapr_startPeriod,
							sapr_endYear, sapr_endPeriod, this.authenticatedUser.SupportingPartnerId, true);
					}
					summaryData.TableName = ExcelTemplateReport.MC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion
				}
				#endregion

				#region Writing summary data
				progressInfo.log = "Writing to Excel sheet summary data. Please wait...";
				backgroundWorker.ReportProgress(progress, progressInfo);
				report.DataSource = summaryDataSet;
				report.WriteDataToExcelSheet(excelWorksheet, SUMMARY_SHEET, 0, 0);
				excelWorkbook.Save();
				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorksheet = null;
				if (backgroundWorker.CancellationPending)
				{
					excelWorkbook.Close(true, misValue, misValue);
					excelApplication.Quit();

					ReleaseObject(excelWorksheet);
					ReleaseObject(excelSheets);
					ReleaseObject(excelWorkbook);
					ReleaseObject(excelWorkbooks);
					ReleaseObject(excelApplication);
					operationCanceled = true;
					return false;
				}
				#endregion

				#region Retrieving Report data
				int facilityCount = facilitiesDetails.Rows.Count;
				int facilityIndex = 0;
				int totalWork = facilityCount * 4;
				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = totalWork;
				string template = "{0} in {1} | {2} ({3} of {4}): Loading {5} report data, please wait...";
				List<DataSet> facilitiesDataSet = new List<DataSet>();
				foreach (DataRow row in facilitiesDetails.Rows)
				{
					facilityIndex++;
					string facilityCode = row["FacCode"].ToString();
					string facilityName = row["FacName"].ToString();
					string districtName = row["District"].ToString();
					string regionName = row["RegionName"].ToString();

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "ANC");
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataSet facilityDataset = new DataSet();
					DataTable data = Utilities.GetFacilityReport(facilityCode,
						ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					data.TableName = ExcelTemplateReport.ANC_TABLE;
					facilityDataset.Tables.Add(data);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "PCR");
					backgroundWorker.ReportProgress(progress, progressInfo);
					data = Utilities.GetFacilityReport(facilityCode,
						PCR_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					data.TableName = ExcelTemplateReport.PCR_TABLE;
					facilityDataset.Tables.Add(data);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "MAT");
					backgroundWorker.ReportProgress(progress, progressInfo);
					data = Utilities.GetFacilityReport(facilityCode, MAT_REPORT_ID,
						sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					data.TableName = ExcelTemplateReport.MAT_TABLE;
					facilityDataset.Tables.Add(data);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "MC");
					backgroundWorker.ReportProgress(progress, progressInfo);
					data = Utilities.GetFacilityReport(facilityCode, MC_REPORT_ID,
						sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					data.TableName = ExcelTemplateReport.MC_TABLE;
					facilityDataset.Tables.Add(data);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}

					DataTable facilityInfo = new DataTable();
					DataColumn column = new DataColumn("FACCODE", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("FACILITYNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("DISTRICTNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("REGIONNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					string[] values = { facilityCode, facilityName, districtName, regionName };
					facilityInfo.Rows.Add(values);
					facilityInfo.TableName = ExcelTemplateReport.FACILITY_INFO_TABLE;
					facilityDataset.Tables.Add(facilityInfo);

					facilitiesDataSet.Add(facilityDataset);
				}
				#endregion

				#region Writing data to excel
				excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(2);
				int columnOffset = 0;
				int rowOffset = 0;
				template = @"Writing to Facility data to Excel Sheet [{0} of {1}]";
				facilityIndex = 0;
				facilityCount = facilitiesDataSet.Count;

				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = facilityCount;
				foreach (DataSet facilityDataSet in facilitiesDataSet)
				{
					facilityIndex++;
					progressInfo.log = String.Format(template, facilityIndex, facilityCount);
					progressInfo.value = facilityIndex;
					backgroundWorker.ReportProgress(facilityIndex, progressInfo);

					// Writing facility column in the sheet.
					WriteFacilitiesInExcelSheet(excelWorksheet, report, facilityDataSet,
						DATA_SHEET, facilityCount, columnOffset, rowOffset);
					rowOffset++;
					excelWorkbook.Save();
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
				}
				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorksheet = null;
				#endregion

				progress = -1;
				progressInfo.log = "Closing Excel and releasing resources. Please wait...";
				backgroundWorker.ReportProgress(progress, progressInfo);
				excelWorkbook.Close(true, misValue, misValue);
				excelApplication.Quit();

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				progress = 100;
				progressInfo.log = "Ready";
				progressInfo.minValue = 0;
				progressInfo.maxValue = 100;
				progressInfo.value = 100;
				backgroundWorker.ReportProgress(progress, progressInfo);
				return true;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, AppConfiguration.ApplicationName,
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				try
				{
					excelWorkbook.Close(true, misValue, misValue);
				}
				catch { }
				try
				{
					excelApplication.Quit();
				}
				catch { }

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				progress = -1;
				SAPRProgress progressInfo = new SAPRProgress();
				progressInfo.minValue = 0;
				progressInfo.maxValue = 100;
				progressInfo.log = "Error occured while trying to generate report";
				backgroundWorker.ReportProgress(progress, progressInfo);
				return false;
			}
			finally
			{
				if (excelWorkbook != null)
				{
					try
					{
						excelWorkbook.Close(true, misValue, misValue);
					}
					catch { }
					try
					{
						excelApplication.Quit();
					}
					catch { }
				}

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);
			}
		}

		private bool GeneratePMTCTMonthlyReport()
		{
			const int LAST_ROW_NUMBER = 75;
			//const int TEMPLATE_ID = 2;
            const string TARGET_TEMPLATE_FILENAME = "PMTCT Monthly Report.xlsx";

			Excel.Application excelApplication = null;
			Excel.Workbooks excelWorkbooks = null;
			Excel.Workbook excelWorkbook = null;
			Excel.Sheets excelWorksheets = null;
			Excel.Worksheet excelWorkSheet = null;
			Excel.Worksheet masterExcelWorkSheet = null;
			object misValue = System.Reflection.Missing.Value;

			SAPRProgress progressInfo = new SAPRProgress();
			int progress = 0;
			try
			{
                var templates = ExcelTemplateReport.GetExcelTemplateReports(ExcelTemplateType.NOT_SAPR_APR, false);
                ExcelTemplateReport excelReport = null;
                foreach (var t in templates)
                {
                    if (t.Filename == TARGET_TEMPLATE_FILENAME)
                    {
                        excelReport = t;
                        break;
                    }
                }

                if (excelReport == null) throw new Exception("Target Excel Template is missing. Missing filename is " + TARGET_TEMPLATE_FILENAME);

				//ExcelTemplateReport excelReport = new ExcelTemplateReport(TEMPLATE_ID);
				string templatePath = String.Format(@"{0}\Resources\{1}", Application.StartupPath, excelReport.Filename);
				string excelTemplateSheetName = excelReport.Sheets[0].TemplateSheetName;
				System.IO.File.Delete(m_SelectedFilePath);
				System.IO.File.Copy(templatePath, m_SelectedFilePath);

				excelApplication = new Excel.Application();
				excelWorkbooks = excelApplication.Workbooks;
				excelWorkbook = excelWorkbooks.Open(m_SelectedFilePath, 0, false, 5,
					"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
				excelWorksheets = excelWorkbook.Worksheets;

				int currentSheetIndex = 1;
				masterExcelWorkSheet = (Excel.Worksheet)excelWorksheets.get_Item(currentSheetIndex);     // 1-based index

				int startYear = pmtct_startYear;
				int startPeriod = pmtct_startPeriod;
				int endYear = pmtct_endYear;
				int endPeriod = pmtct_endPeriod;
                bool createSummationSheet = false;  // Indicates whether we need to create another sheet for the summation of data
                if (startYear != endYear) createSummationSheet = true;
                else
                {
                    if (startPeriod != endPeriod) createSummationSheet = true;
                }

				progress = -1;
				// Get all facilities in particular district, district or nation   
				progressInfo.log = "Retrieving list of facilities...";
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable facilitiesDetails = null;
				if (pmtct_districtsSelected) facilitiesDetails = Utilities.GetFacilitiesDetailsByDistrict(pmtct_districtID, true);
				if (pmtct_regionsSelected) facilitiesDetails = Utilities.GetFacilitiesDetailsByRegion(pmtct_regionID, true);
				if (pmtct_nationSelected) facilitiesDetails = Utilities.GetAllFacilitiesDetails(true, true);

				progressInfo.log = String.Format("Found {0} facilities", facilitiesDetails.Rows.Count);
				backgroundWorker.ReportProgress(progress, progressInfo);

				// Retrieving the complete dataset
				Dictionary<string, List<DataSet>> facilitiesDataset = GeneratePMTCTMonthlyReport3(
					startYear, startPeriod, endYear, endPeriod, facilitiesDetails);                

                if (backgroundWorker.CancellationPending || operationCanceled)
				{
					excelWorkbook.Close(true, misValue, misValue);
					excelApplication.Quit();

					//ReleaseObject(excelWorksheet);
					ReleaseObject(excelWorksheets);
					ReleaseObject(excelWorkbook);
					ReleaseObject(excelWorkbooks);
					ReleaseObject(excelApplication);
					operationCanceled = true;
					return false;
				}
				if (facilitiesDataset == null) return false;

                #region Creating Summary Sheet Data
                if (createSummationSheet)
                {
                    string key = string.Format("{0}|{1}|{2}|{3}", startPeriod, startYear, endPeriod, endYear);
                    List<DataSet> facilitiesSummaryDataSet = new List<DataSet>();

                    // We will start by going through each facility
                    for (int i = 0; i < facilitiesDetails.Rows.Count; i++)
                    {
                        DataTable ANCData = null;
                        DataTable PCRData = null;
                        DataTable MATData = null;
                        DataTable MCData = null;
                        DataTable facilityInfo = null;
                        DataSet facilityMonthsDataSet = new DataSet();

                        // Going each month of particular facility to get the reports
                        foreach (string month in facilitiesDataset.Keys)
                        {
                            List<DataSet> facilitiesInMonthDataset = facilitiesDataset[month];
                            DataSet facilityMonthDataset = facilitiesInMonthDataset[i];

                            // In each month, facility dataset contains facilityInfo.
                            // This information is always the same, we'll retrieve it only once.
                            if (facilityInfo == null)
                            {
                                DataTable infoTable = facilityMonthDataset.Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
                                facilityInfo = infoTable.Copy();
                            }

                            DataTable ancTable = facilityMonthDataset.Tables[ExcelTemplateReport.ANC_TABLE];
                            if (ANCData == null)
                            {
                                ANCData = ancTable.Copy();
                                ANCData.Columns[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ReadOnly = false;
                            }
                            else IncrementDataTableValuesIntoAnotherTable(ancTable, ANCData);

                            DataTable pcrTable = facilityMonthDataset.Tables[ExcelTemplateReport.PCR_TABLE];
                            if (PCRData == null)
                            {
                                PCRData = pcrTable.Copy();
                                PCRData.Columns[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ReadOnly = false;
                            }
                            else IncrementDataTableValuesIntoAnotherTable(pcrTable, PCRData);

                            DataTable matTable = facilityMonthDataset.Tables[ExcelTemplateReport.MAT_TABLE];
                            if (MATData == null)
                            {
                                MATData = matTable.Copy();
                                MATData.Columns[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ReadOnly = false;
                            }
                            else IncrementDataTableValuesIntoAnotherTable(matTable, MATData);

                            DataTable mcTable = facilityMonthDataset.Tables[ExcelTemplateReport.MC_TABLE];
                            if (MCData == null)
                            {
                                MCData = mcTable.Copy();
                                MCData.Columns[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ReadOnly = false;
                            }
                            else IncrementDataTableValuesIntoAnotherTable(mcTable, MCData);
                        }

                        facilityMonthsDataSet.Tables.Add(ANCData);
                        facilityMonthsDataSet.Tables.Add(PCRData);
                        facilityMonthsDataSet.Tables.Add(MATData);
                        facilityMonthsDataSet.Tables.Add(MCData);
                        facilityMonthsDataSet.Tables.Add(facilityInfo);

                        facilitiesSummaryDataSet.Add(facilityMonthsDataSet);
                    }

                    facilitiesDataset[key] = facilitiesSummaryDataSet;
                }
                #endregion

				int totalWork = 0;
				foreach (string month in facilitiesDataset.Keys)
				{
					List<DataSet> facilitiesMonthData = facilitiesDataset[month];
					foreach (DataSet facilityData in facilitiesMonthData) totalWork++;
				}
				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = totalWork;

				string labelTamplate = "Writing to Excel: Sheet {0} [{1} of {2}]: {3} [{4} of {5}]";
				Excel.Worksheet lastWorkSheet = masterExcelWorkSheet;
				int sheetCount = 0;
				foreach (string month in facilitiesDataset.Keys)
				{
					sheetCount++;
					#region Create a sheet from master template.
					masterExcelWorkSheet.Copy(misValue, lastWorkSheet);
					currentSheetIndex++;
					if (excelWorkSheet != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkSheet);
					excelWorkSheet = null;
					excelWorkSheet = (Excel.Worksheet)excelWorksheets.get_Item(currentSheetIndex);
					Excel.Range cells = excelWorkSheet.Cells;

					List<DataSet> facilitiesMonthData = facilitiesDataset[month];
					Excel.Range range = null;
					int facilityCount = facilitiesMonthData.Count;
					int columnOffset = 0;
					int rowOffset = 0;
					int rowIndex = 2;
					#endregion

					#region Putting sheet name
					string[] components = month.Split('|');
                    string sheetLabel = string.Empty;
                    if (components.Length == 4 && createSummationSheet)
                    {
                        int iStartMonth = Int32.Parse(components[0]);
                        int iStartYear = Int32.Parse(components[1]);
                        int iEndMonth = Int32.Parse(components[2]);
                        int iEndYear = Int32.Parse(components[3]);
                        string startMonthText = Utilities.GetMonthText(iStartMonth, true);
                        string endMonthText = Utilities.GetMonthText(iEndMonth, true);
                        sheetLabel = String.Format("{0} {1} - {2} {3}", 
                            startMonthText, iStartYear, endMonthText, iEndYear);
                        excelWorkSheet.Name = sheetLabel;
                    }
                    else
                    {
                        int iMonth = Int32.Parse(components[0]);
                        int iYear = Int32.Parse(components[1]);
                        string monthText = Utilities.GetMonthText(iMonth, true);
                        sheetLabel = String.Format("{0} {1}", monthText, iYear);
                        excelWorkSheet.Name = sheetLabel;
                    }
					#endregion

					// Deteriming the district name
					DataTable dataTable = facilitiesMonthData[0].Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
					DataRow row = dataTable.Rows[0];
					string previousDistrict = row["DISTRICTNAME"].ToString();

					int firstColumnIndex = 2;
					int lastColumnIndex = firstColumnIndex;
					int facilityIndex = 0;

					foreach (DataSet facilityData in facilitiesMonthData)
					{
						#region Writing data of facilities
						dataTable = facilityData.Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
						row = dataTable.Rows[0];
						string district = row["DISTRICTNAME"].ToString();
						string facilityName = row["FACILITYNAME"].ToString();
						facilityIndex++;

						progress++;
						progressInfo.value = progress;
						progressInfo.log = String.Format(labelTamplate, sheetLabel, sheetCount,
							facilitiesDataset.Keys.Count, facilityName, facilityIndex, facilityCount);
						backgroundWorker.ReportProgress(progress, progressInfo);

						// Writing facility column in the sheet.
						WriteFacilitiesInExcelSheet3(excelWorkSheet, excelReport,
							facilityData, excelTemplateSheetName, facilityCount, columnOffset, rowOffset);

						if (previousDistrict != district)
						{
							#region Creating merged cell and put the district name in it
							rowIndex = 2;
							//columnIndex = 2 + columnOffset - 1;                            
							Excel.Range cell = (Excel.Range)cells[rowIndex, firstColumnIndex];
							cell.Value = previousDistrict;
							System.Runtime.InteropServices.Marshal.ReleaseComObject(cell);
							cell = null;

							if (range != null)
							{
								System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
								range = null;
							}
							object r = cells[rowIndex, firstColumnIndex];
							object c = cells[rowIndex, lastColumnIndex - 1];
							range = excelWorkSheet.Range[r, c];
							range.Merge(misValue);

							System.Runtime.InteropServices.Marshal.ReleaseComObject(r);
							r = null;
							System.Runtime.InteropServices.Marshal.ReleaseComObject(c);
							c = null;

							r = cells[rowIndex, firstColumnIndex];
							c = cells[74, firstColumnIndex];
							range = excelWorkSheet.Range[r, c];
							range.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlMedium;

							System.Runtime.InteropServices.Marshal.ReleaseComObject(r);
							r = null;
							System.Runtime.InteropServices.Marshal.ReleaseComObject(c);
							c = null;

							System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
							range = null;

							previousDistrict = district;
							firstColumnIndex = lastColumnIndex;
							lastColumnIndex = firstColumnIndex + 1;
							#endregion
						}
						else lastColumnIndex++;
						columnOffset++;
						#endregion
					}
					//excelWorkbook.Save();

					// Writing name of the last district 
					Excel.Range d = (Excel.Range)cells[rowIndex, firstColumnIndex];
					d.Value = previousDistrict;
					if (range != null)
					{
						System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
						range = null;
					}

					object dr = cells[rowIndex, firstColumnIndex];
					object dc = cells[rowIndex, lastColumnIndex - 1];
					range = excelWorkSheet.Range[dr, dc];
					range.Merge(misValue);

					System.Runtime.InteropServices.Marshal.ReleaseComObject(dr);
					System.Runtime.InteropServices.Marshal.ReleaseComObject(dc);
					System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
					dr = null;
					dc = null;
					range = null;

					dr = cells[rowIndex, firstColumnIndex];
					dc = cells[LAST_ROW_NUMBER, lastColumnIndex - 1];
					range = excelWorkSheet.Range[dr, dc];
					range.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlMedium;

					lastWorkSheet = excelWorkSheet;
					progressInfo.log = "Saving workbook...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					excelWorkbook.Save();
				}

				progress = -1;
				progressInfo.log = "Closing Excel...";
				backgroundWorker.ReportProgress(progress, progressInfo);

				// Delete the template
				excelApplication.DisplayAlerts = false;
				masterExcelWorkSheet.Delete();
				excelWorkbook.Save();

				excelWorkbook.Close(true, misValue, misValue);
				excelApplication.Quit();

				ReleaseObject(excelWorkSheet);
				ReleaseObject(masterExcelWorkSheet);
				ReleaseObject(excelWorksheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				progressInfo.log = "Ready";
				backgroundWorker.ReportProgress(progress, progressInfo);
				return true;
			}
			catch (Exception ex)
			{
                string details = string.Empty;
                if (ex.InnerException != null) details = "\n\nFurther details: " + ex.InnerException.Message;

				MessageBox.Show(ex.Message + details, AppConfiguration.ApplicationName,
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				try
				{
					excelWorkbook.Close(true, misValue, misValue);
				}
				catch { }
				try
				{
					excelApplication.Quit();
				}
				catch { }

				ReleaseObject(excelWorkSheet);
				ReleaseObject(masterExcelWorkSheet);
				ReleaseObject(excelWorksheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				backgroundWorker.ReportProgress(progress, ex);
				return false;
			}
			finally
			{
				if (excelWorkbook != null)
				{
					try
					{
						excelWorkbook.Close(true, misValue, misValue);
					}
					catch { }
					try
					{
						excelApplication.Quit();
					}
					catch { }
				}

				ReleaseObject(excelWorkSheet);
				ReleaseObject(excelWorksheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);
			}
		}

		private void WriteFacilitiesInExcelSheet3(Excel.Worksheet excelWorkSheet,
			ExcelTemplateReport excelReport, DataSet dataset,
			string templateSheetName, int facilityCount, int columnOffset, int rowOffset)
		{
			object misValue = System.Reflection.Missing.Value;
			excelReport.DataSource = dataset;
			excelReport.WriteDataToExcelSheet(excelWorkSheet, templateSheetName, columnOffset, rowOffset);

			foreach (ExcelTemplateSheet sheet in excelReport.Sheets)
			{
				if (sheet.TemplateSheetName == templateSheetName)
				{
					if (sheet.HasRepetitiveRows)
					{
						if (facilityCount > (rowOffset + 3))
						{
							//Insert new row
							int rowIndex = sheet.FirstRepetitiveRowCellIndex + rowOffset + 1;
							Excel.Range cells = excelWorkSheet.Rows;
							Excel.Range range = (Excel.Range)cells[rowIndex, misValue];
							range.Insert(misValue, Excel.XlInsertFormatOrigin.xlFormatFromLeftOrAbove);

							System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
							System.Runtime.InteropServices.Marshal.ReleaseComObject(cells);
							range = null;
							cells = null;
						}
					}

					if (sheet.HasRepetitveColumns)
					{
						if ((facilityCount > (columnOffset + 3)))
						{
							//Insert new column
							int columnIndex = sheet.FirstRepetitiveColumnCellIndex + columnOffset + 1;
							//Excel.Range range = excelWorkSheet.get_Range(
							//    excelWorkSheet.Cells[1, columnIndex],
							//    excelWorkSheet.Cells[excelWorkSheet.Rows.Count, columnIndex]);
							object r = excelWorkSheet.Cells[1, columnIndex];
							object c = excelWorkSheet.Cells[excelWorkSheet.Rows.Count, columnIndex];
							Excel.Range range = excelWorkSheet.Range[r, c];
							range.Insert(misValue, Excel.XlInsertShiftDirection.xlShiftToRight);

							System.Runtime.InteropServices.Marshal.ReleaseComObject(r);
							System.Runtime.InteropServices.Marshal.ReleaseComObject(c);
							System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
							r = null;
							c = null;
							range = null;
						}
					}
					break;
				}
			}
		}

		private Dictionary<string, List<DataSet>> GeneratePMTCTMonthlyReport3(int startYear, int startPeriod,
			int endYear, int endPeriod, DataTable facilitiesDetails)
		{
			Dictionary<string, List<DataSet>> facilitiesDataSet = new Dictionary<string, List<DataSet>>();
			// Retrieving each report, for each facility, for each month.           

			if (startYear == endYear)
			{
				FindDataSetByMonths3(startYear, startPeriod, endPeriod, facilitiesDetails, facilitiesDataSet);
				if (backgroundWorker.CancellationPending) return null;
                if (operationCanceled) return null;
			}
			else
			{
				int currentYear = startYear;
				do
				{
					int startingPeriod = 1;
					int endingPeriod = 12;
					if (currentYear == startYear) startingPeriod = startPeriod;
					if (currentYear == endYear) endingPeriod = endPeriod;

					FindDataSetByMonths3(currentYear, startingPeriod, endingPeriod, facilitiesDetails, facilitiesDataSet);
					if (backgroundWorker.CancellationPending) return null;
                    if (operationCanceled) return null;
					currentYear++;
				} while (currentYear <= endYear);
			}
			return facilitiesDataSet;
		}

		private void FindDataSetByMonths3(int year, int startPeriod, int endPeriod,
			DataTable facilitiesDetails, Dictionary<string, List<DataSet>> facilitiesMonthsDataSet)
		{
			int progress = 0;
			int totalWork = (endPeriod - startPeriod + 1) * facilitiesDetails.Rows.Count;
			SAPRProgress progressInfo = new SAPRProgress();
			progressInfo.minValue = 0;
			progressInfo.maxValue = totalWork;

			// Going through each month independently
			for (int p = startPeriod; p <= endPeriod; p++)
			{
				if (backgroundWorker.CancellationPending) return;
				string key = String.Format("{0}|{1}", p, year);
				List<DataSet> facilitiesMonthDataSet = new List<DataSet>();
				string template = "{0} in {1} | {2} ({3} of {4}): Loading data for {5} {6}";
				int index = 0;


				// Now for each month, find report of each facility presented.
				foreach (DataRow row in facilitiesDetails.Rows)
				{
					index++;
					string facilityCode = row["FacCode"].ToString();
					string facilityName = row["FacName"].ToString();
					string districtName = row["District"].ToString();
					string regionName = row["RegionName"].ToString();
					string monthText = Utilities.GetMonthText(p);

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template,
						districtName, regionName, facilityName, index,
						facilitiesDetails.Rows.Count, monthText, year);
					backgroundWorker.ReportProgress(progress, progressInfo);
					//if (backgroundWorker.CancellationPending) return;

					DataSet facilityMonthDataset = new DataSet();
                    Dictionary<int, DataTable> basicReportsData = PersistentlyLoadData(facilityCode, year, p);
                    if (basicReportsData == null) // Operation cancelled by user
                    {
                        // may be we could add more loggic here
                        operationCanceled = true;
                        return;
                    }
                    else
                    {
                        foreach (int reportIdKey in basicReportsData.Keys)
                        {
                            DataTable dataTable = basicReportsData[reportIdKey];
                            facilityMonthDataset.Tables.Add(dataTable);
                        }
                    }

                    //DataTable data = Utilities.GetFacilityReport(facilityCode,
                    //    ANC_REPORT_ID, year, p, year, p, true);
                    //data.TableName = ExcelTemplateReport.ANC_TABLE;
                    //facilityMonthDataset.Tables.Add(data);
                    ////if (backgroundWorker.CancellationPending) return;

                    //data = Utilities.GetFacilityReport(facilityCode,
                    //    PCR_REPORT_ID, year, p, year, p, true);
                    //data.TableName = ExcelTemplateReport.PCR_TABLE;
                    //facilityMonthDataset.Tables.Add(data);
                    ////if (backgroundWorker.CancellationPending) return;

                    //data = Utilities.GetFacilityReport(facilityCode,
                    //    MAT_REPORT_ID, year, p, year, p, true);
                    //data.TableName = ExcelTemplateReport.MAT_TABLE;
                    //facilityMonthDataset.Tables.Add(data);
                    ////if (backgroundWorker.CancellationPending) return;

                    //data = Utilities.GetFacilityReport(facilityCode,
                    //    MC_REPORT_ID, year, p, year, p, true);
                    //data.TableName = ExcelTemplateReport.MC_TABLE;
                    //facilityMonthDataset.Tables.Add(data);
					//if (backgroundWorker.CancellationPending) return;

					DataTable facilityInfo = new DataTable();
					DataColumn column = new DataColumn("FACCODE", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("FACILITYNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("DISTRICTNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn("REGIONNAME", Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					string[] values = { facilityCode, facilityName, districtName, regionName };
					facilityInfo.Rows.Add(values);
					facilityInfo.TableName = ExcelTemplateReport.FACILITY_INFO_TABLE;
					facilityMonthDataset.Tables.Add(facilityInfo);

					facilitiesMonthDataSet.Add(facilityMonthDataset);
				}
				//facilitiesDataSet.Add(facilitiesMonthDataSet);
				facilitiesMonthsDataSet[key] = facilitiesMonthDataSet;
				//facilitiesDataSet.Add(facilitiesMonthDataSetD);
			}
		}

        /// <summary>
        /// Loads data persistently.
        /// The method offers an opportunity to retry the operation once failed.
        /// </summary>
        /// <param name="facilityCode"></param>
        /// <param name="year"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private Dictionary<int, DataTable> PersistentlyLoadData(string facilityCode, int year, int p)
        {
            const int ANC_REPORT_ID = 6;
            //const int PCR_REPORT_ID = 19;
            const int PCR_REPORT_ID = 8;
            const int MAT_REPORT_ID = 7;
            const int MC_REPORT_ID = 9;

            //List<DataTable> reportsData = new List<DataTable>();
            Dictionary<int, DataTable> reportsData = new Dictionary<int, DataTable>();
            bool operationAborted = false;
            do
            {
                try
                {
                    if (!reportsData.ContainsKey(ANC_REPORT_ID))
                    {
                        DataTable ANCData = Utilities.GetFacilityReport(facilityCode,
                            ANC_REPORT_ID, year, p, year, p, true);
                        ANCData.TableName = ExcelTemplateReport.ANC_TABLE;
                        reportsData[ANC_REPORT_ID] = ANCData;
                    }

                    if (!reportsData.ContainsKey(PCR_REPORT_ID))
                    {
                        DataTable PCRData = Utilities.GetFacilityReport(facilityCode,
                            PCR_REPORT_ID, year, p, year, p, true);
                        PCRData.TableName = ExcelTemplateReport.PCR_TABLE;
                        reportsData[PCR_REPORT_ID] = PCRData;
                    }

                    if (!reportsData.ContainsKey(MAT_REPORT_ID))
                    {
                        DataTable MATData = Utilities.GetFacilityReport(facilityCode,
                            MAT_REPORT_ID, year, p, year, p, true);
                        MATData.TableName = ExcelTemplateReport.MAT_TABLE;
                        reportsData[MAT_REPORT_ID] = MATData;
                    }

                    if (!reportsData.ContainsKey(MC_REPORT_ID))
                    {
                        DataTable MCData = Utilities.GetFacilityReport(facilityCode,
                            MC_REPORT_ID, year, p, year, p, true);
                        MCData.TableName = ExcelTemplateReport.MC_TABLE;
                        reportsData[MC_REPORT_ID] = MCData;
                    }

                    break;
                }
                catch (Exception ex)
                {
                    DialogResult response = MessageBox.Show(
                        string.Format("The following error occured:\n\n{0}", ex.Message),
                        AppConfiguration.ApplicationName, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                    if (response == System.Windows.Forms.DialogResult.Cancel)
                    {
                        operationAborted = true;
                        break;
                    }
                }
            } while (true);

            if (operationAborted) return null;
            else return reportsData;
        }

        /// <summary>
        /// Add the values of the dataSource DataTable object to the values of dataDestination DataTable object
        /// e.g. If in the first row the values of dataSource and dataDestination is 3 and 5 respectively, 
        /// then dataDestination will have 8.
        /// </summary>
        /// <remarks>The two tables must have the same schema, otherwise the result may be unexpected</remarks>
        /// <param name="dataSource">Data Source</param>
        /// <param name="dataDestination">Data Destionation, this is where the increment occurs</param>
        private void IncrementDataTableValuesIntoAnotherTable(DataTable dataSource, DataTable dataDestination)
        {
            for (int k = 0; k < dataSource.Rows.Count; k++)
            {
                DataRow sourceRow = dataSource.Rows[k];
                DataRow destinationRow = dataDestination.Rows[k];

                int sourceValue = int.Parse(sourceRow[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ToString());
                int destinationValue = int.Parse(destinationRow[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME].ToString());
                int newValue = destinationValue + sourceValue;

                destinationRow[REPORT_DETAILS_REPORT_DATA_COLUMN_NAME] = newValue;
            }
        }

		void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			btnCancel.Enabled = true;
			progressBar.Visible = false;
			btnCancel.Visible = false;

			if (operationCanceled)
			{
				lblProgress.Text = "Operation Cancelled";
				toolStripStatusLabel.Text = "Operation Cancelled";
				System.IO.File.Delete(m_SelectedFilePath);
			}
			else
			{
                if (e.Error != null || !operationSucceeded)
                {
                    string errorMessage = e.Error != null
                        ? "An error occured, operation did not complete successfully\n\n" + e.Error.Message
                        : "An error occured, operation did not complete successfully\n\n";

                    MessageBox.Show(errorMessage, AppConfiguration.ApplicationName,
                        MessageBoxButtons.OK, MessageBoxIcon.Error);

                    System.IO.File.Delete(m_SelectedFilePath);
                }
                else
                {
                    if (operationSucceeded)
                    {
                        lblProgress.Text = "Operation completed";
                        toolStripStatusLabel.Text = "Operation completed";
                        Application.DoEvents();

                        DialogResult response = MessageBox.Show(
                            String.Format("Report has been generated successfully. It has been saved in {0}" +
                                ".\n\nDo you want to open it?", m_SelectedFilePath),
                            AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        if (response == System.Windows.Forms.DialogResult.Yes)
                        {
                            try
                            {
                                System.Diagnostics.Process.Start(m_SelectedFilePath);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(
                                    String.Format("Failed to open the file.{0}{0}Error details:{0}{1}",
                                        Environment.NewLine, ex.Message),
                                    AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                    else
                    {
                        MessageBox.Show("An error occured, operation did not complete successfully",
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        System.IO.File.Delete(m_SelectedFilePath);
                    }
                }
			}

			groupBox8.Enabled = true;
			cboAggregation.Enabled = true;
			cboStartYear.Enabled = true;
			cboStartPeriod.Enabled = true;

			cboEndYear.Enabled = true;
			cboEndPeriod.Enabled = true;

			btnGenerateDonorReport.Enabled = true;
			btnGenerateSAPR.Enabled = true;
			btnGeneratePMTCTMonthlyReport.Enabled = true;
			btnGenerateSAPRPromise.Enabled = true;

			lblProgress.Visible = false;
			progressBar.Visible = false;
			btnCancel.Visible = false;

			generatingSAPR = false;
			generatingSAPRPromise = false;
			generatingPMTCT = false;
		}

		void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			try
			{
				SAPRProgress progressInfo = (SAPRProgress)e.UserState;
				toolStripStatusLabel.Text = progressInfo.log;
				lblProgress.Text = progressInfo.log;
				if (e.ProgressPercentage == -1)
				{
					progressBar.Style = ProgressBarStyle.Marquee;
					progressBar.Minimum = 0;
					progressBar.Maximum = 100;
					progressBar.Value = 45;
				}
				else
				{
					progressBar.Minimum = progressInfo.minValue;
					progressBar.Maximum = progressInfo.maxValue;
					progressBar.Value = progressInfo.value;
					progressBar.Style = ProgressBarStyle.Continuous;
				}
			}
			catch (Exception ex)
			{
				//toolStripStatusLabel.Text = e.UserState.ToString();
				//lblProgress.Text = e.UserState.ToString();
			}
		}

		void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
		{
            operationCanceled = false;
			if (generatingSAPR) operationSucceeded = GenerateSAPR();
			if (generatingSAPRPromise) operationSucceeded = GeneratePromiseSAPR();
			if (generatingPMTCT) operationSucceeded = GeneratePMTCTMonthlyReport();
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			if (backgroundWorker != null)
			{
				if (backgroundWorker.IsBusy)
				{
					DialogResult response = MessageBox.Show(this,
						"Are you sure you want to cancel the current operation?",
						AppConfiguration.ApplicationName,
						MessageBoxButtons.YesNo, MessageBoxIcon.Question);
					if (response == System.Windows.Forms.DialogResult.Yes)
					{
						btnCancel.Enabled = false;
						operationCanceled = true;
						backgroundWorker.CancelAsync();
					}
				}
			}
		}

		private DataTable ReadExcelSheet(Excel.Worksheet excelSheet, int startRow, int startColumn, int rows, int columns)
		{
			Excel.Range excelCells = excelSheet.Cells;
			DataTable dataTable = new DataTable();
			if (rows == -1)
			{

			}
			else
			{

			}

			if (columns == -1)
			{

			}
			else
			{
				for (int i = 0; i < columns; i++)
				{
					DataColumn c = new DataColumn();
					c.ColumnName = String.Format("Dummy_{0}", i);
					c.DataType = Type.GetType("System.String");
					dataTable.Columns.Add(c);
				}

				bool okToContinue = true;
				int currentRow = startRow;
				while (okToContinue)
				{
					Excel.Range excelCell = (Excel.Range)excelCells[currentRow, startColumn];
					string value = (string)excelCell.Value;
					if (String.IsNullOrEmpty(value)) okToContinue = false;
					else
					{
						DataRow dataRow = dataTable.NewRow();
						for (int i = 0; i < columns; i++)
						{
							Excel.Range cell = (Excel.Range)excelCells[currentRow, startColumn + i];
							value = (string)cell.Value;
							dataRow[i] = value;
							ReleaseObject(cell);
						}
						dataTable.Rows.Add(dataRow);
						currentRow++;
					}
					ReleaseObject(excelCell);
				}
				ReleaseObject(excelCells);
				return dataTable;
			}
			return dataTable;
		}

        [Obsolete("Never used before why starting now", true)]
		private DataTable ReadExcelSheet(Excel.Worksheet excelSheet, int startRow, int startColumn)
		{
			const string _7 = "7";
			const string _8 = "8";
			const string _9 = "9";
			const string _11 = "11";
			const string _13 = "13";
			const string _31 = "31";
			const string _32 = "32";
			const string _33 = "33";
			const string _40 = "40";
			const string _41 = "41";
			const string _93 = "93";
			const string _94 = "94";
			const string _95 = "95";

			int columns = 4;
			Excel.Range excelCells = excelSheet.Cells;
			DataTable dataTable = new DataTable();

			if (columns == -1)
			{

			}
			else
			{
				/*for (int i = 0; i < columns; i++)
				{
					DataColumn c = new DataColumn();
					c.ColumnName = String.Format("Dummy_{0}", i);
					c.DataType = Type.GetType("System.String");
					dataTable.Columns.Add(c);
				}*/
				#region DataTable columns
				DataColumn c = new DataColumn();
				c.ColumnName = REGION_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = DISTRICT_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = FACILITY_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _7;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _8;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _9;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _11;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _13;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _31;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _32;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _33;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _40;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _41;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _93;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _94;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _95;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);
				#endregion

				bool okToContinue = true;
				int currentRow = startRow;
				while (okToContinue)
				{
					string value = String.Empty;
					Excel.Range excelCell = (Excel.Range)excelCells[currentRow, startColumn];
					if (excelCell.Value == null) okToContinue = false;
					else value = excelCell.Value.ToString();

					if (String.IsNullOrEmpty(value)) okToContinue = false;
					else
					{
						DataRow dataRow = dataTable.NewRow();
						for (int i = 3; i < 6; i++)
						{
							Excel.Range cell = (Excel.Range)excelCells[currentRow, i];
							value = cell.Value.ToString();
							dataRow[i - 3] = value;
							ReleaseObject(cell);
						}

						for (int i = 3; i < dataTable.Columns.Count; i++)
						{
							string columnName = dataTable.Columns[i].ColumnName;
							int columnIndex = Int32.Parse(columnName);
							Excel.Range cell = (Excel.Range)excelCells[currentRow, columnIndex];
							value = (0).ToString();
							try
							{
								value = cell.Value.ToString();
							}
							catch { }
							dataRow[i] = value;
							ReleaseObject(cell);
						}
						dataTable.Rows.Add(dataRow);
						currentRow++;
					}
					ReleaseObject(excelCell);
				}
				ReleaseObject(excelCells);
				#region Renaming columns to reflect APR
				dataTable.Columns[_31].ColumnName = "36";
				dataTable.Columns[_32].ColumnName = "37";
				dataTable.Columns[_33].ColumnName = "38";
				dataTable.Columns[_40].ColumnName = "45";
				dataTable.Columns[_41].ColumnName = "46";
				dataTable.Columns[_95].ColumnName = "96";
				#endregion

				return dataTable;
			}
			return dataTable;
		}

		/// <summary>
		/// Read the APR/SAPR data and use it the baseline for producing the other template data.
		/// </summary>
		/// <param name="excelSheet"></param>
		/// <param name="startRow"></param>
		/// <param name="startColumn"></param>
		/// <param name="i"></param>
		/// <returns></returns>
		private DataTable ReadExcelSheet(Excel.Worksheet excelSheet, int startRow, int startColumn, string iiiiiiii)
		{
			#region Data columns in the incoming excel sheet
			const string _7 = "7";
			const string _8 = "8";
			const string _9 = "9";
			const string _11 = "11";
			const string _13 = "13";
			const string _14 = "14";
			const string _16 = "16";
			const string _45 = "45";
			const string _47 = "47";
			const string _48 = "48";
			const string _58 = "58";
			const string _59 = "59";
			const string _60 = "60";
			const string _61 = "61";
			const string _62 = "62";
			const string _115 = "115";
			const string _116 = "116";
			const string _117 = "117";
			const string _118 = "118";
			const string _119 = "119";
			#endregion

			int columns = 4; // The next column after this contains facility name
			Excel.Range excelCells = excelSheet.Cells;
			DataTable dataTable = new DataTable();

			if (columns == -1)
			{

			}
			else
			{
				#region DataTable columns - based on tempalate data target columns
				DataColumn c = new DataColumn();
				c.ColumnName = REGION_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = DISTRICT_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = FACILITY_NAME;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _7;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _8;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _9;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _11;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _13;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _14;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _16;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _45;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _47;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _48;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _58;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _59;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _60;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _61;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _62;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _115;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _116;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _117;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _118;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);

				c = new DataColumn();
				c.ColumnName = _119;
				c.DataType = Type.GetType("System.String");
				dataTable.Columns.Add(c);
				#endregion

				bool okToContinue = true;
				int currentRow = startRow;
				while (okToContinue)
				{
					string value = String.Empty;
					Excel.Range excelCell = (Excel.Range)excelCells[currentRow, startColumn];
					if (excelCell.Value == null) okToContinue = false;
					else value = excelCell.Value.ToString();

					if (String.IsNullOrEmpty(value)) okToContinue = false;
					else
					{
						DataRow dataRow = dataTable.NewRow();
						// Filing the region, district and facility
						for (int i = 3; i < 6; i++)
						{
							Excel.Range cell = (Excel.Range)excelCells[currentRow, i];
							value = cell.Value.ToString();
							dataRow[i - 3] = value;
							ReleaseObject(cell);
						}

						// Filling selected columns
						for (int i = 3; i < dataTable.Columns.Count; i++)
						{
							string columnName = dataTable.Columns[i].ColumnName;
							int columnIndex = Int32.Parse(columnName);
							Excel.Range cell = (Excel.Range)excelCells[currentRow, columnIndex];
							value = (0).ToString();
							try
							{
								value = cell.Value.ToString();
							}
							catch { }
							dataRow[i] = value;
							ReleaseObject(cell);
						}
						dataTable.Rows.Add(dataRow);
						currentRow++;
					}
					ReleaseObject(excelCell);
				}
				ReleaseObject(excelCells);
				#region Renaming columns to reflect APR
				dataTable.Columns[_119].ColumnName = "120";
				dataTable.Columns[_118].ColumnName = "119";
				dataTable.Columns[_117].ColumnName = "118";
				dataTable.Columns[_116].ColumnName = "117";
				dataTable.Columns[_115].ColumnName = "116";
				#endregion

				return dataTable;
			}
			return dataTable;
		}

        /// <summary>
        /// Read the SAPR data and use it as the baseline for producing the APR
        /// </summary>
        /// <param name="excelSheet">Excel sheet which point to the SAPR data</param>
        /// <param name="sheetInfo">Data extraction rules for existing SAPR sheet</param>
        /// <param name="startRow"></param>
        /// <param name="startColumn"></param>
        /// <returns></returns>
        private DataTable ReadPreviousExcelSheetData(Excel.Worksheet excelSheet, 
            ExcelTemplateSheet sheetInfo, int startRow, int startColumn)
        {
            int columns = 4; // The next column after this contains facility name
            Excel.Range excelCells = excelSheet.Cells;
            DataTable dataTable = new DataTable();

            if (columns != -1)
            {
                #region DataTable columns - based on tempalate data target columns
                DataColumn c = new DataColumn();
                c.ColumnName = REGION_NAME;
                c.DataType = Type.GetType("System.String");
                dataTable.Columns.Add(c);

                c = new DataColumn();
                c.ColumnName = DISTRICT_NAME;
                c.DataType = Type.GetType("System.String");
                dataTable.Columns.Add(c);

                c = new DataColumn();
                c.ColumnName = FACILITY_NAME;
                c.DataType = Type.GetType("System.String");
                dataTable.Columns.Add(c);

                foreach (var cellInfo in sheetInfo.Cells)
                {
                    if (cellInfo.IndicatorDataSource == REGION_NAME) continue;
                    if (cellInfo.IndicatorDataSource == DISTRICT_NAME) continue;
                    if (cellInfo.IndicatorDataSource == FACILITY_NAME) continue;

                    c = new DataColumn();
                    //int columnIndex = ExcelTemplateReport.GetColumnNumber(cellInfo.CellAddress);
                    //c.ColumnName = columnIndex.ToString();
                    c.ColumnName = cellInfo.CellAddress;
                    c.DataType = Type.GetType("System.String");
                    dataTable.Columns.Add(c);
                }
                #endregion

                bool okToContinue = true;
                int currentRow = startRow;
                while (okToContinue)
                {
                    string value = String.Empty;
                    Excel.Range excelCell = (Excel.Range)excelCells[currentRow, startColumn];
                    if (excelCell.Value == null) okToContinue = false;
                    else value = excelCell.Value.ToString();

                    if (String.IsNullOrEmpty(value)) okToContinue = false;
                    else
                    {
                        DataRow dataRow = dataTable.NewRow();
                        // Filing the region, district and facility
                        for (int i = 3; i < 6; i++)
                        {
                            Excel.Range cell = (Excel.Range)excelCells[currentRow, i];
                            value = cell.Value.ToString();
                            dataRow[i - 3] = value;
                            ReleaseObject(cell);
                        }

                        // Filling selected columns
                        for (int i = 3; i < dataTable.Columns.Count; i++)
                        {
                            string columnName = dataTable.Columns[i].ColumnName; 
                            //int columnIndex = Int32.Parse(columnName);                            
                            //Excel.Range cell = (Excel.Range)excelCells[currentRow, columnIndex];
                            string address = Regex.Replace(columnName, @"[\d-]", currentRow.ToString());
                            Excel.Range cell = (Excel.Range)excelCells[address];
                            value = (0).ToString();
                            try
                            {
                                value = cell.Value.ToString();
                            }
                            catch { }
                            dataRow[i] = value;
                            ReleaseObject(cell);
                        }
                        dataTable.Rows.Add(dataRow);
                        currentRow++;
                    }
                    ReleaseObject(excelCell);
                }

                ReleaseObject(excelCells);
                return dataTable;
            }
            return dataTable;
        }

		private bool GeneratePromiseSAPR()
		{
			#region Function Constants and Variables
			//const int MARA_MWANZA_TEMPLATE_ID = 3;
			//const int TANGA_TEMPLATE_ID = 4;
			//const int MISSING_TEMPLATE_ID = 5;

			// April 2013 Format
			//const int MARA_MWANZA_TEMPLATE_ID = 6;
			//const int TANGA_TEMPLATE_ID = 7;
			//const int MISSING_TEMPLATE_ID = 8;

			// October 2013 Format
			const int MARA_TANGA_TEMPLATE_ID = 9;
			const int TANGA_MANYARA_TEMPLATE_ID = 10;
			const int MISSING_TEMPLATE_ID = 11;

			//const string SUMMARY_SHEET = "Summary";
			//const string DATA_SHEET = "Data";
			const string INDICATOR_DATA_ENTRY = "Indicator Data Entry";
			const string MISSING_FACILITIES = "Missing Facilities";

			const int TEMPLATE_START_ROW = 22;
			const int TEMPLATE_START_COLUMN = 3;

			const int ANC_REPORT_ID = 6;
			const int PCR_REPORT_ID = 8;
			const int MAT_REPORT_ID = 7;
			const int MC_REPORT_ID = 9;

			string MAX_ANC = String.Format("MAX_{0}", ExcelTemplateReport.ANC_TABLE);
			string MAX_PCR = String.Format("MAX_{0}", ExcelTemplateReport.PCR_TABLE);
			string MAX_MAT = String.Format("MAX_{0}", ExcelTemplateReport.MAT_TABLE);
			string MAX_MC = String.Format("MAX_{0}", ExcelTemplateReport.MC_TABLE);

			int progress = -1;
			//string log = String.Empty;
			object misValue = System.Reflection.Missing.Value;
			completed = false;

			Excel.Application excelApplication = null;
			Excel.Workbooks excelWorkbooks = null;
			Excel.Workbook excelWorkbook = null;
			Excel.Sheets excelSheets = null;
			Excel.Worksheet excelWorksheet = null;

			Excel.Workbook excelWorkbook_IndexMaraMwanza = null;
			Excel.Sheets excelSheets_IndexMaraMwanza = null;
			Excel.Worksheet excelWorksheet_IndexMaraMwanza = null;

			Excel.Workbook excelWorkbook_IndexTanga = null;
			Excel.Sheets excelSheets_IndexTanga = null;
			Excel.Worksheet excelWorksheet_IndexTanga = null;
			#endregion

			try
			{
                //ExcelTemplateReport MaraMwanzaReportTemplate = new ExcelTemplateReport(MARA_TANGA_TEMPLATE_ID);
                //ExcelTemplateReport TangaReportTemplate = new ExcelTemplateReport(TANGA_MANYARA_TEMPLATE_ID);
                //ExcelTemplateReport missingReportTemplate = new ExcelTemplateReport(MISSING_TEMPLATE_ID);

                ExcelTemplateReport MaraMwanzaReportTemplate = (from et in PromisTemplateSelector.ExcelTemplateReports
                                                                where et.TemplateID == MARA_TANGA_TEMPLATE_ID
                                                                select et).FirstOrDefault();

                ExcelTemplateReport TangaReportTemplate = (from et in PromisTemplateSelector.ExcelTemplateReports
                                                           where et.TemplateID == TANGA_MANYARA_TEMPLATE_ID
                                                           select et).FirstOrDefault();

                ExcelTemplateReport missingReportTemplate = (from et in PromisTemplateSelector.ExcelTemplateReports
                                                             where et.TemplateID == MISSING_TEMPLATE_ID
                                                             select et).FirstOrDefault();

				ExcelTemplateCellCollection cells = MaraMwanzaReportTemplate.Sheets[0].Cells;
				string templatePath = String.Format(@"{0}\Resources\{1}", Application.StartupPath, MaraMwanzaReportTemplate.Filename);
				//System.IO.File.Delete(m_SelectedFilePath);
				string destinationFilename = String.Format(@"{0}\{1}", m_SelectedFilePath, MaraMwanzaReportTemplate.Filename);
				System.IO.File.Copy(templatePath, destinationFilename, true);

				excelApplication = new Excel.Application();
				excelWorkbooks = excelApplication.Workbooks;
				excelWorkbook = excelWorkbooks.Open(destinationFilename, 0, false, 5,
					"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

				int currentSheetIndex = 5;
				excelSheets = excelWorkbook.Worksheets;
				excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheetIndex);     // 1-based index

				const int STARTING_ROW = 22;
				const int STARTING_COLUMN = 3;
				const int ROWS = -1;
				const int COLUMNS = 3; 
				const string TRUE = "TRUE";

				SAPRProgress progressInfo = new SAPRProgress();
				progressInfo.log = "Retrieving list of target facilities from Excel file. Please wait...";
				progressInfo.value = -1;
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable targetFacilities = ReadExcelSheet(excelWorksheet, STARTING_ROW, STARTING_COLUMN, ROWS, COLUMNS);

				#region Indexing Excel sheet Values
				DataTable indexSAPRMaraMwanza = null;
				DataTable indexSAPRTanga = null;
				if (sapr_useBaselineData)
				{
					//destinationFilename = String.Format(@"{0}\Resources\12045_FP_Catholic Relief Services_SAPR2012_12.xls", Application.StartupPath);
					destinationFilename = String.Format(@"{0}\Resources\Baseline_{1}", Application.StartupPath, MaraMwanzaReportTemplate.Filename);
					excelWorkbook_IndexMaraMwanza = excelWorkbooks.Open(destinationFilename, 0, false, 5,
						"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
					currentSheetIndex = 5; // The target sheet is the fifth
					excelSheets_IndexMaraMwanza = excelWorkbook_IndexMaraMwanza.Worksheets;
					excelWorksheet_IndexMaraMwanza = (Excel.Worksheet)excelSheets_IndexMaraMwanza.get_Item(currentSheetIndex);     // 1-based index
					indexSAPRMaraMwanza = ReadExcelSheet(excelWorksheet_IndexMaraMwanza, TEMPLATE_START_ROW, TEMPLATE_START_COLUMN, String.Empty);
					excelWorkbook_IndexMaraMwanza.Close(false, misValue, misValue);

					destinationFilename = String.Format(@"{0}\Resources\Baseline_{1}", Application.StartupPath, TangaReportTemplate.Filename);
					excelWorkbook_IndexTanga = excelWorkbooks.Open(destinationFilename, 0, false, 5,
						"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
					currentSheetIndex = 5;  // The target sheet is the fifth
					excelSheets_IndexTanga = excelWorkbook_IndexTanga.Worksheets;
					excelWorksheet_IndexTanga = (Excel.Worksheet)excelSheets_IndexTanga.get_Item(currentSheetIndex);     // 1-based index
					indexSAPRTanga = ReadExcelSheet(excelWorksheet_IndexTanga, TEMPLATE_START_ROW, TEMPLATE_START_COLUMN, String.Empty);
					excelWorkbook_IndexTanga.Close(false, misValue, misValue);
				}
				#endregion

				#region Get all facilities in particular district, district or nation
				DataTable facilitiesDetails = null;
				DataSet summaryDataSet = new DataSet();

				progressInfo.log = "Retrieving records from database. Please wait...";
				progressInfo.value = -1;
				backgroundWorker.ReportProgress(progress, progressInfo);

				if (sapr_districtsSelected)
				{
					operationCanceled = true;
					return false;
				}
				if (sapr_regionsSelected)
				{
					operationCanceled = true;
					return false;
				};

				if (sapr_nationSelected)
				{

					progressInfo.log = "Retrieving list of facilities. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					//facilitiesDetails = Utilities.GetAllFacilitiesDetails(true, true);
					facilitiesDetails = Utilities.GetAllFacilitiesDetails_Alpha();
					//facilitiesDetails = Utilities.GetAllFacilitiesDetails();
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
#if NORMAL_SAPR
					#region Retrieving Nation Summary Data
					progressInfo.log = "Retrieving facilities ANC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataTable summaryData = Utilities.GetNationReport(
						ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					summaryData.TableName = ExcelTemplateReport.ANC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						return;
					}

					progressInfo.log = "Retrieving facilities PCR reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					summaryData = Utilities.GetNationReport(PCR_REPORT_ID,
						sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					summaryData.TableName = ExcelTemplateReport.PCR_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						return;
					}

					progressInfo.log = "Retrieving facilities MAT reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					summaryData = Utilities.GetNationReport(MAT_REPORT_ID,
						sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					summaryData.TableName = ExcelTemplateReport.MAT_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						return;
					}

					progressInfo.log = "Retrieving facilities MC reports. Please wait...";
					backgroundWorker.ReportProgress(progress, progressInfo);
					summaryData = Utilities.GetNationReport(MC_REPORT_ID,
						sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
					summaryData.TableName = ExcelTemplateReport.MC_TABLE;
					summaryDataSet.Tables.Add(summaryData);
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						return;
					}
					#endregion
#endif
				}
				#endregion

#if NORMAL_SAPR
				#region Writing summary data
				progressInfo.log = "Writing to Excel sheet summary data. Please wait...";
				backgroundWorker.ReportProgress(progress, progressInfo);
				report.DataSource = summaryDataSet;
				report.WriteDataToExcelSheet(excelWorksheet, SUMMARY_SHEET, 0, 0);
				excelWorkbook.Save();
				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorksheet = null;
				if (backgroundWorker.CancellationPending)
				{
					excelWorkbook.Close(true, misValue, misValue);
					excelApplication.Quit();

					ReleaseObject(excelWorksheet);
					ReleaseObject(excelSheets);
					ReleaseObject(excelWorkbook);
					ReleaseObject(excelWorkbooks);
					ReleaseObject(excelApplication);
					return;
				}
				#endregion
#endif

				#region Retrieving Report data
				#region Bulk Retrieval of data
				DateTime startDate = DateTime.Parse(String.Format("{0:0000}-{1:00}-01", sapr_startYear, sapr_startPeriod));
				DateTime endDate = DateTime.Parse(String.Format("{0:0000}-{1:00}-28", sapr_endYear, sapr_endPeriod));

				progress = 0;
				progressInfo.minValue = 0;
				if (sapr_useMaximumValues) progressInfo.maxValue = 8;
				else progressInfo.maxValue = 4;

				progressInfo.value = progress;
				progressInfo.log = String.Format("Loading ANC Reports: {0} {1} - {2} {3}, please wait...", 
					Utilities.GetMonthText(startDate.Month), startDate.Year, Utilities.GetMonthText(endDate.Month), endDate.Year);
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable ANC_Reports = Utilities.GetBulkEachFacilityReport(ANC_REPORT_ID, startDate, endDate);

				progress++;
				progressInfo.value = progress;
				progressInfo.log = String.Format("Loading PCR Reports: {0} {1} - {2} {3}, please wait...",
					Utilities.GetMonthText(startDate.Month), startDate.Year, Utilities.GetMonthText(endDate.Month), endDate.Year);
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable PCR_Reports = Utilities.GetBulkEachFacilityReport(PCR_REPORT_ID, startDate, endDate);

				progress++;
				progressInfo.value = progress;
				progressInfo.log = String.Format("Loading MAT Reports: {0} {1} - {2} {3}, please wait...",
					Utilities.GetMonthText(startDate.Month), startDate.Year, Utilities.GetMonthText(endDate.Month), endDate.Year);
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable MAT_Reports = Utilities.GetBulkEachFacilityReport(MAT_REPORT_ID, startDate, endDate);

				progress++;
				progressInfo.value = progress;
				progressInfo.log = String.Format("Loading MC Reports: {0} {1} - {2} {3}, please wait...",
					Utilities.GetMonthText(startDate.Month), startDate.Year, Utilities.GetMonthText(endDate.Month), endDate.Year);
				backgroundWorker.ReportProgress(progress, progressInfo);
				DataTable MC_Reports = Utilities.GetBulkEachFacilityReport(MC_REPORT_ID, startDate, endDate);

				DataTable Max_ANC_Reports = null;
				DataTable Max_PCR_Reports = null;
				DataTable Max_MAT_Reports = null;
				DataTable Max_MC_Reports = null;
				if (sapr_useMaximumValues)
				{
					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format("Loading ANC Reports: {0} {1} - {2} {3}, please wait...",
						Utilities.GetMonthText(sapr_useMax_startDate.Month), sapr_useMax_startDate.Year, 
						Utilities.GetMonthText(sapr_useMax_endDate.Month), sapr_useMax_endDate.Year);
					backgroundWorker.ReportProgress(progress, progressInfo);
					Max_ANC_Reports = Utilities.GetBulkEachFacilityReport(ANC_REPORT_ID, sapr_useMax_startDate, sapr_useMax_endDate);

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format("Loading PCR Reports: {0} {1} - {2} {3}, please wait...",
						Utilities.GetMonthText(sapr_useMax_startDate.Month), sapr_useMax_startDate.Year, 
						Utilities.GetMonthText(sapr_useMax_endDate.Month), sapr_useMax_endDate.Year);
					backgroundWorker.ReportProgress(progress, progressInfo);
					Max_PCR_Reports = Utilities.GetBulkEachFacilityReport(PCR_REPORT_ID, sapr_useMax_startDate, sapr_useMax_endDate);

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format("Loading MAT Reports: {0} {1} - {2} {3}, please wait...",
						Utilities.GetMonthText(sapr_useMax_startDate.Month), sapr_useMax_startDate.Year, 
						Utilities.GetMonthText(sapr_useMax_endDate.Month), sapr_useMax_endDate.Year);
					backgroundWorker.ReportProgress(progress, progressInfo);
					Max_MAT_Reports = Utilities.GetBulkEachFacilityReport(MAT_REPORT_ID, sapr_useMax_startDate, sapr_useMax_endDate);

					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format("Loading MC Reports: {0} {1} - {2} {3}, please wait...",
						Utilities.GetMonthText(sapr_useMax_startDate.Month), sapr_useMax_startDate.Year, 
						Utilities.GetMonthText(sapr_useMax_endDate.Month), sapr_useMax_endDate.Year);
					backgroundWorker.ReportProgress(progress, progressInfo);
					Max_MC_Reports = Utilities.GetBulkEachFacilityReport(MC_REPORT_ID, sapr_useMax_startDate, sapr_useMax_endDate);
				}
				#endregion

				int facilityCount = facilitiesDetails.Rows.Count;
				int facilityIndex = 0;
				int totalWork = facilityCount * 4;
				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = totalWork;
				string template = "{0} in {1} | {2} ({3} of {4}): Loading {5} report data, please wait...";
				List<DataSet> facilitiesDataSet = new List<DataSet>();
				foreach (DataRow row in facilitiesDetails.Rows)
				{
					facilityIndex++;
					string facilityCode = row["FacCode"].ToString();
					//string facilityName = row["FacName"].ToString();
					string facilityName = row["InternalName"].ToString();
					string facilityType = row["FacilityType"].ToString();
					string provideDBS = row["ProvideDBS"].ToString();
					string districtName = row["District"].ToString();
					string regionName = row["RegionName"].ToString();

					DataTable max_DataTemplate = new DataTable();
					DataColumn c = new DataColumn("Data Description", Type.GetType("System.String"));
					max_DataTemplate.Columns.Add(c);
					c = new DataColumn("ReportData", Type.GetType("System.Int32"));
					max_DataTemplate.Columns.Add(c);

					#region ANC
					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "ANC");
					backgroundWorker.ReportProgress(progress, progressInfo);
					DataSet facilityDataset = new DataSet();
					DataTable data = null; // this table consists of two column Data Description and ReportData
					DataTable max_Data = null;                    

					try
					{
						int nextFirstTrialIndex = 0;
						bool nextFirtTrialIndexFound = false;
						#region Processing Bulk data and put into more suitable format
						for (int k = 0; k < ANC_Reports.Rows.Count; k++)
						{
							DataRow r = ANC_Reports.Rows[k];

							string code = r["FacCode"].ToString();
							if (code == facilityCode)
							{
								data = new DataTable();
								c = new DataColumn("Data Description", Type.GetType("System.String"));
								data.Columns.Add(c);
								c = new DataColumn("ReportData", Type.GetType("System.Int32"));
								data.Columns.Add(c);
								nextFirstTrialIndex = k;
								nextFirtTrialIndexFound = true;

								for (int i = 1; i < ANC_Reports.Columns.Count; i++)
								{
									string columnName = ANC_Reports.Columns[i].ColumnName;
									int reportData = 0;
									Int32.TryParse(r[columnName].ToString(), out reportData);

									DataRow indicatorDataRow = data.NewRow();
									indicatorDataRow[0] = columnName;
									indicatorDataRow[1] = reportData;
									data.Rows.Add(indicatorDataRow);
								}

								ANC_Reports.Rows.Remove(r); //Minimize repetitions
								break;
							}
						}
						#endregion

						#region Indexing data for Picking maximum values
						if (sapr_useMaximumValues)
						{
							bool found = false;
							if (nextFirtTrialIndexFound) // This is for quick search, in case the table have same facilities in the same order.
							{                                
								try
								{
									DataRow r = Max_ANC_Reports.Rows[nextFirstTrialIndex];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										found = true;
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_ANC_Reports.Columns.Count; i++)
										{
											string columnName = Max_ANC_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_ANC_Reports.Rows.Remove(r); //Minimize repetitions
									}
								}
								catch
								{
									found = false;
								}
							}
							
							if (!found)
							{
								for (int k = 0; k < Max_ANC_Reports.Rows.Count; k++)
								{
									DataRow r = Max_ANC_Reports.Rows[k];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_ANC_Reports.Columns.Count; i++)
										{
											string columnName = Max_ANC_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_ANC_Reports.Rows.Remove(r); //Minimize repetitions
										break;
									}
								}
							}
						}
						#endregion
					}
					#region This is just the old fall back, I don't expect it to be used
					catch //This is just the old fall back, I don't expect it to be used
					{
						do
						{
							try
							{
								data = Utilities.GetFacilityReport(facilityCode,
									ANC_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
								break;
							}
							catch (Exception ex)
							{
								DialogResult response = MessageBox.Show(this, ex.Message,
									String.Format("{0} - Error retrieving data", AppConfiguration.ApplicationName),
									MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								if (response == System.Windows.Forms.DialogResult.Cancel) throw ex;
							}
						} while (true);
					}
					#endregion

					data.TableName = ExcelTemplateReport.ANC_TABLE;
					if (sapr_useMaximumValues) max_Data.TableName = MAX_ANC;

					#region This is the Clement special request
					DataTable anc = data;
					DataRow anc04Row = anc.Rows[3];
					DataRow anc08Row = anc.Rows[7];
					int anc04 = 0;
					int anc08 = 0;
					Int32.TryParse(anc04Row[0].ToString(), out anc04);
					Int32.TryParse(anc08Row[0].ToString(), out anc08);
					if (anc08 < anc04)
					{
						DataRow anc06Row = anc.Rows[5];
						int anc06 = 0;
						Int32.TryParse(anc06Row[0].ToString(), out anc06);
						if ((anc04 == anc06) && (anc08 == 0))
						{
							DataRow anc07Row = anc.Rows[6];
							int anc07 = 0;
							Int32.TryParse(anc07Row[0].ToString(), out anc07);

							anc06Row[0] = anc07;
							anc07Row[0] = anc08;
							anc08Row[0] = anc06;
						}
					}

					if (sapr_useMaximumValues)
					{
						anc = max_Data;
						anc04Row = anc.Rows[3];
						anc08Row = anc.Rows[7];
						anc04 = 0;
						anc08 = 0;
						Int32.TryParse(anc04Row[0].ToString(), out anc04);
						Int32.TryParse(anc08Row[0].ToString(), out anc08);
						if (anc08 < anc04)
						{
							DataRow anc06Row = anc.Rows[5];
							int anc06 = 0;
							Int32.TryParse(anc06Row[0].ToString(), out anc06);
							if ((anc04 == anc06) && (anc08 == 0))
							{
								DataRow anc07Row = anc.Rows[6];
								int anc07 = 0;
								Int32.TryParse(anc07Row[0].ToString(), out anc07);

								anc06Row[0] = anc07;
								anc07Row[0] = anc08;
								anc08Row[0] = anc06;
							}
						}
					}
					#endregion

					facilityDataset.Tables.Add(data);
					if (sapr_useMaximumValues) facilityDataset.Tables.Add(max_Data);
					
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion

					#region PCR
					data = null;
					max_Data = null;
					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "PCR");
					backgroundWorker.ReportProgress(progress, progressInfo);

					try
					{
						int nextFirstTrialIndex = 0;
						bool nextFirtTrialIndexFound = false;
						#region Processing Bulk data and put into more suitable format
						for (int k = 0; k < PCR_Reports.Rows.Count; k++)
						{
							DataRow r = PCR_Reports.Rows[k];

							string code = r["FacCode"].ToString();
							if (code == facilityCode)
							{
								data = new DataTable();
								c = new DataColumn("Data Description", Type.GetType("System.String"));
								data.Columns.Add(c);
								c = new DataColumn("ReportData", Type.GetType("System.Int32"));
								data.Columns.Add(c);
								nextFirstTrialIndex = k;
								nextFirtTrialIndexFound = true;

								for (int i = 1; i < PCR_Reports.Columns.Count; i++)
								{
									string columnName = PCR_Reports.Columns[i].ColumnName;
									int reportData = 0;
									Int32.TryParse(r[columnName].ToString(), out reportData);

									DataRow indicatorDataRow = data.NewRow();
									indicatorDataRow[0] = columnName;
									indicatorDataRow[1] = reportData;
									data.Rows.Add(indicatorDataRow);
								}

								PCR_Reports.Rows.Remove(r); //Minimize repetitions
								break;
							}
						}
						#endregion

						#region Indexing data for Picking maximum values
						if (sapr_useMaximumValues)
						{
							bool found = false;
							if (nextFirtTrialIndexFound) // This is for quick search, in case the table have same facilities in the same order.
							{
								try
								{
									DataRow r = Max_PCR_Reports.Rows[nextFirstTrialIndex];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										found = true;
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_PCR_Reports.Columns.Count; i++)
										{
											string columnName = Max_PCR_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_PCR_Reports.Rows.Remove(r); //Minimize repetitions
									}
								}
								catch
								{
									found = false;
								}
							}

							if (!found)
							{
								for (int k = 0; k < Max_PCR_Reports.Rows.Count; k++)
								{
									DataRow r = Max_PCR_Reports.Rows[k];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_PCR_Reports.Columns.Count; i++)
										{
											string columnName = Max_PCR_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_PCR_Reports.Rows.Remove(r); //Minimize repetitions
										break;
									}
								}
							}
						}
						#endregion
					}
					#region This is just the old fall back, I don't expect it to be used
					catch
					{
						do
						{
							try
							{
								data = Utilities.GetFacilityReport(facilityCode,
									PCR_REPORT_ID, sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
								break;
							}
							catch (Exception ex)
							{
								DialogResult response = MessageBox.Show(this, ex.Message,
									String.Format("{0} - Error retrieving data", AppConfiguration.ApplicationName),
									MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								if (response == System.Windows.Forms.DialogResult.Cancel) throw ex;
							}
						} while (true);
					}
					#endregion

					data.TableName = ExcelTemplateReport.PCR_TABLE;
					facilityDataset.Tables.Add(data);
					if (sapr_useMaximumValues)
					{
						max_Data.TableName = MAX_PCR;
						facilityDataset.Tables.Add(max_Data);
					}

					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion

					#region MAT
					data = null;
					max_Data = null;
					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "MAT");
					backgroundWorker.ReportProgress(progress, progressInfo);

					try
					{
						int nextFirstTrialIndex = 0;
						bool nextFirtTrialIndexFound = false;
						#region Processing Bulk data and put into more suitable format
						for (int k = 0; k < MAT_Reports.Rows.Count; k++)
						{
							DataRow r = MAT_Reports.Rows[k];

							string code = r["FacCode"].ToString();
							if (code == facilityCode)
							{
								data = new DataTable();
								c = new DataColumn("Data Description", Type.GetType("System.String"));
								data.Columns.Add(c);
								c = new DataColumn("ReportData", Type.GetType("System.Int32"));
								data.Columns.Add(c);
								nextFirstTrialIndex = k;
								nextFirtTrialIndexFound = true;

								for (int i = 1; i < MAT_Reports.Columns.Count; i++)
								{
									string columnName = MAT_Reports.Columns[i].ColumnName;
									int reportData = 0;
									Int32.TryParse(r[columnName].ToString(), out reportData);

									DataRow indicatorDataRow = data.NewRow();
									indicatorDataRow[0] = columnName;
									indicatorDataRow[1] = reportData;
									data.Rows.Add(indicatorDataRow);
								}

								MAT_Reports.Rows.Remove(r); //Minimize repetitions
								break;
							}
						}
						#endregion

						#region Indexing data for Picking maximum values
						if (sapr_useMaximumValues)
						{
							bool found = false;
							if (nextFirtTrialIndexFound) // This is for quick search, in case the table have same facilities in the same order.
							{
								try
								{
									DataRow r = Max_MAT_Reports.Rows[nextFirstTrialIndex];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										found = true;
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_MAT_Reports.Columns.Count; i++)
										{
											string columnName = Max_MAT_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_MAT_Reports.Rows.Remove(r); //Minimize repetitions
									}
								}
								catch
								{
									found = false;
								}
							}

							if (!found)
							{
								for (int k = 0; k < Max_MAT_Reports.Rows.Count; k++)
								{
									DataRow r = Max_MAT_Reports.Rows[k];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_MAT_Reports.Columns.Count; i++)
										{
											string columnName = Max_MAT_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_MAT_Reports.Rows.Remove(r); //Minimize repetitions
										break;
									}
								}
							}
						}
						#endregion
					}
					#region This is just the old fall back, I don't expect it to be used
					catch
					{
						do
						{
							try
							{
								data = Utilities.GetFacilityReport(facilityCode, MAT_REPORT_ID,
									sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
								break;
							}
							catch (Exception ex)
							{
								DialogResult response = MessageBox.Show(this, ex.Message,
									String.Format("{0} - Error retrieving data", AppConfiguration.ApplicationName),
									MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								if (response == System.Windows.Forms.DialogResult.Cancel) throw ex;
							}
						} while (true);
					}
					#endregion

					data.TableName = ExcelTemplateReport.MAT_TABLE;
					facilityDataset.Tables.Add(data);
					if (sapr_useMaximumValues)
					{
						max_Data.TableName = MAX_MAT;
						facilityDataset.Tables.Add(max_Data);
					}

					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion

					#region MC
					data = null;
					max_Data = null;
					progress++;
					progressInfo.value = progress;
					progressInfo.log = String.Format(template, districtName, regionName,
						facilityName, facilityIndex, facilityCount, "MC");
					backgroundWorker.ReportProgress(progress, progressInfo);

					try
					{
						int nextFirstTrialIndex = 0;
						bool nextFirtTrialIndexFound = false;
						#region Processing Bulk data and put into more suitable format
						for (int k = 0; k < MC_Reports.Rows.Count; k++)
						{
							DataRow r = MC_Reports.Rows[k];

							string code = r["FacCode"].ToString();
							if (code == facilityCode)
							{
								data = new DataTable();
								c = new DataColumn("Data Description", Type.GetType("System.String"));
								data.Columns.Add(c);
								c = new DataColumn("ReportData", Type.GetType("System.Int32"));
								data.Columns.Add(c);
								nextFirstTrialIndex = k;
								nextFirtTrialIndexFound = true;

								for (int i = 1; i < MC_Reports.Columns.Count; i++)
								{
									string columnName = MC_Reports.Columns[i].ColumnName;
									int reportData = 0;
									Int32.TryParse(r[columnName].ToString(), out reportData);

									DataRow indicatorDataRow = data.NewRow();
									indicatorDataRow[0] = columnName;
									indicatorDataRow[1] = reportData;
									data.Rows.Add(indicatorDataRow);
								}

								MC_Reports.Rows.Remove(r); //Minimize repetitions
								break;
							}
						}
						#endregion

						#region Indexing data for Picking maximum values
						if (sapr_useMaximumValues)
						{
							bool found = false;
							if (nextFirtTrialIndexFound) // This is for quick search, in case the table have same facilities in the same order.
							{
								try
								{
									DataRow r = Max_MC_Reports.Rows[nextFirstTrialIndex];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										found = true;
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_MC_Reports.Columns.Count; i++)
										{
											string columnName = Max_MC_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_MC_Reports.Rows.Remove(r); //Minimize repetitions
									}
								}
								catch
								{
									found = false;
								}
							}

							if (!found)
							{
								for (int k = 0; k < Max_MC_Reports.Rows.Count; k++)
								{
									DataRow r = Max_MC_Reports.Rows[k];
									string code = r["FacCode"].ToString();
									if (code == facilityCode)
									{
										max_Data = new DataTable();
										c = new DataColumn("Data Description", Type.GetType("System.String"));
										max_Data.Columns.Add(c);
										c = new DataColumn("ReportData", Type.GetType("System.Int32"));
										max_Data.Columns.Add(c);

										for (int i = 1; i < Max_MC_Reports.Columns.Count; i++)
										{
											string columnName = Max_MC_Reports.Columns[i].ColumnName;
											int reportData = 0;
											Int32.TryParse(r[columnName].ToString(), out reportData);

											DataRow indicatorDataRow = max_Data.NewRow();
											indicatorDataRow[0] = columnName;
											indicatorDataRow[1] = reportData;
											max_Data.Rows.Add(indicatorDataRow);
										}

										Max_MC_Reports.Rows.Remove(r); //Minimize repetitions
										break;
									}
								}
							}
						}
						#endregion
					}
					#region This is just the old fall back, I don't expect it to be used
					catch
					{
						do
						{
							try
							{
								data = Utilities.GetFacilityReport(facilityCode, MC_REPORT_ID,
									sapr_startYear, sapr_startPeriod, sapr_endYear, sapr_endPeriod, true);
								break;
							}
							catch (Exception ex)
							{
								DialogResult response = MessageBox.Show(this, ex.Message,
									String.Format("{0} - Error retrieving data", AppConfiguration.ApplicationName),
									MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								if (response == System.Windows.Forms.DialogResult.Cancel) throw ex;
							}
						} while (true);
					}
					#endregion

					data.TableName = ExcelTemplateReport.MC_TABLE;
					facilityDataset.Tables.Add(data);
					if (sapr_useMaximumValues)
					{
						max_Data.TableName = MAX_MC;
						facilityDataset.Tables.Add(max_Data);
					}

					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
					#endregion

					#region Generating Facility info table
					DataTable facilityInfo = new DataTable();
					DataColumn column = new DataColumn(FACCODE, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(FACILITY_NAME, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(DISTRICT_NAME, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(REGION_NAME, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(FACILITY_TYPE, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(PROVIDEDBS, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(HOSPITAL, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(DISPENSARY, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(HEALTH_CENTRE, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(PMTCTSITE, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					column = new DataColumn(ANCSERVICES, Type.GetType("System.String"));
					facilityInfo.Columns.Add(column);
					string[] values = { 
										  facilityCode, facilityName, districtName, regionName, 
										  facilityType, provideDBS, String.Empty, String.Empty, 
										  String.Empty, TRUE, "TRUE"
									  };
					facilityInfo.Rows.Add(values);
					facilityInfo.TableName = ExcelTemplateReport.FACILITY_INFO_TABLE;
					#endregion
					facilityDataset.Tables.Add(facilityInfo);

					facilitiesDataSet.Add(facilityDataset);
				}
				#endregion

				#region Processing File - Mara & Mwanza
				DataTable reportingValues = null;
				if (sapr_useMaximumValues)
				{
					reportingValues = new DataTable();
					DataColumn c = new DataColumn("Region", Type.GetType("System.String"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("District", Type.GetType("System.String"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("Facility", Type.GetType("System.String"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("Submitted SAPR", Type.GetType("System.Int32"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("System SAPR", Type.GetType("System.Int32"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("System APR", Type.GetType("System.Int32"));
					reportingValues.Columns.Add(c);

					c = new DataColumn("APR = SAPR + 6 Months", Type.GetType("System.Int32"));
					reportingValues.Columns.Add(c);
				}

				#region Writing data to excel
				//excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(2);
				int columnOffset = 0;
				int rowOffset = 0;
				template = @"Writing to Facility data to Excel Sheet [{0} of {1}]";
				facilityIndex = 0;
				facilityCount = targetFacilities.Rows.Count;

				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = facilityCount;
				foreach (DataRow targetFacility in targetFacilities.Rows)
				{
					facilityIndex++;
					progressInfo.log = String.Format(template, facilityIndex, facilityCount);
					progressInfo.value = facilityIndex;
					backgroundWorker.ReportProgress(facilityIndex, progressInfo);

					string targetRegion = targetFacility[0].ToString();
					string targetDistrict = targetFacility[1].ToString();
					string targetFacilityName = targetFacility[2].ToString();
 
					foreach (DataSet facilityDataSet in facilitiesDataSet)
					{
						DataTable facilityInfo = facilityDataSet.Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
						DataRow r = facilityInfo.Rows[0];
						string name = r[FACILITY_NAME].ToString();
						string district = r[DISTRICT_NAME].ToString();
						string region = r[REGION_NAME].ToString();
						if ((name == targetFacilityName) && (region == targetRegion))
						{
							//string code = r["FACCODE"].ToString();
							bool provideDBS = false;
							Boolean.TryParse(r[PROVIDEDBS].ToString(), out provideDBS);
							if (provideDBS)
							{
								string type = r[FACILITY_TYPE].ToString();
								int iType = FACILITY_TYPE_DISPENSARY;
								Int32.TryParse(type, out iType);
								//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
								//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
								//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

								if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
								if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
								if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
							}
							else // finding DBS using another means i.e. MAT08 > 0
							{
								try
								{
									DataTable mat = facilityDataSet.Tables[ExcelTemplateReport.MAT_TABLE];
									DataRow mat08Row = mat.Rows[7];
									string key = mat08Row[0].ToString();
									string value = mat08Row[1].ToString();
									if (key == "MAT08")
									{
										int iValue = 0;
										Int32.TryParse(value, out iValue);
										if (iValue > 0)
										{
											r[PROVIDEDBS] = true;
											string type = r[FACILITY_TYPE].ToString();
											int iType = FACILITY_TYPE_DISPENSARY;
											Int32.TryParse(type, out iType);
											//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
											//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
											//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

											if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
											if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
											if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
										}
									}
								}
								catch { }
							}

							MaraMwanzaReportTemplate.DataSource = facilityDataSet;
							MaraMwanzaReportTemplate.SimplifyDatasetFormat(true);

							// Adding data from baseline sheets
							if (sapr_useBaselineData)
							{
								Dictionary<int, int> dIndex1 = new Dictionary<int, int>();
								foreach (DataRow x in indexSAPRMaraMwanza.Rows)
								{
									string xName = x[FACILITY_NAME].ToString();
									string xDistrict = x[DISTRICT_NAME].ToString();
									string xRegion = x[REGION_NAME].ToString();
									if ((xName == targetFacilityName) && (xRegion == targetRegion))
									{
										int startingColumn = 3;
										// Now generate the 
										for (int y = startingColumn; y < indexSAPRMaraMwanza.Columns.Count; y++)
										{
											string sColumnName = indexSAPRMaraMwanza.Columns[y].ColumnName;
											int iColumnName = Int32.Parse(sColumnName);
											dIndex1[iColumnName] = Int32.Parse(x[sColumnName].ToString());
										}
										indexSAPRMaraMwanza.Rows.Remove(x);
										break;
									}
								}

								foreach (var z in MaraMwanzaReportTemplate.Sheets)
								{
									z.AddValueToCells(dIndex1);
									if (sapr_useMaximumValues)
									{                                        
										foreach (var c in z.Cells)
										{
											int _6monthsValue = 0;
											int _12mothsValue = 0;
											int _6monthsValueSAPR = 0;
											bool isNumerical = false;
											isNumerical = Int32.TryParse(c.Value, out _6monthsValue);
											if (isNumerical)
											{
												_6monthsValue = c.GetValue(facilityDataSet, ExcelTemplateReport.ANC_TABLE, 
													ExcelTemplateReport.PCR_TABLE, ExcelTemplateReport.MAT_TABLE, ExcelTemplateReport.MC_TABLE);
												_12mothsValue = c.GetValue(facilityDataSet,MAX_ANC, MAX_PCR, MAX_MAT, MAX_MC);
												_6monthsValueSAPR = Int32.Parse(c.Value);

												if (_12mothsValue > _6monthsValueSAPR)
												{
													int extraValue = _12mothsValue - _6monthsValueSAPR;
													int newValue = Int32.Parse(c.Value) + extraValue;
													c.Value = newValue.ToString();
												}
											}
										}
									}
								}
							}
							MaraMwanzaReportTemplate.WriteDataToExcelSheet(excelWorksheet, INDICATOR_DATA_ENTRY, columnOffset, rowOffset, false);
							facilitiesDataSet.Remove(facilityDataSet);  //To reduce looping already processed data
							break;
						}
					}

					rowOffset++;
					//excelWorkbook.Save();
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
				}

				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorkbook.Close(true, misValue, misValue);
				excelWorksheet = null;
				#endregion
				#endregion

				#region Processing File - Tanga & Manyara
				cells = TangaReportTemplate.Sheets[0].Cells;
				templatePath = String.Format(@"{0}\Resources\{1}", Application.StartupPath, TangaReportTemplate.Filename);
				//System.IO.File.Delete(m_SelectedFilePath);
				destinationFilename = String.Format(@"{0}\{1}", m_SelectedFilePath, TangaReportTemplate.Filename);
				System.IO.File.Copy(templatePath, destinationFilename, true);

				excelWorkbook = excelWorkbooks.Open(destinationFilename, 0, false, 5,
					"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
				currentSheetIndex = 5; // The target sheet is the fifth
				excelSheets = excelWorkbook.Worksheets;
				excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheetIndex);     // 1-based index

				progressInfo.log = "Retrieving list of target facilities from Excel file. Please wait...";
				progressInfo.value = -1;
				progress = -1;
				backgroundWorker.ReportProgress(progress, progressInfo);
				targetFacilities = ReadExcelSheet(excelWorksheet, STARTING_ROW, STARTING_COLUMN, ROWS, COLUMNS);

				#region Writing data to excel
				columnOffset = 0;
				rowOffset = 0;
				template = @"Writing to Facility data to Excel Sheet [{0} of {1}]";
				facilityIndex = 0;
				facilityCount = targetFacilities.Rows.Count;

				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = facilityCount;
				foreach (DataRow targetFacility in targetFacilities.Rows)
				{
					facilityIndex++;
					progressInfo.log = String.Format(template, facilityIndex, facilityCount);
					progressInfo.value = facilityIndex;
					backgroundWorker.ReportProgress(facilityIndex, progressInfo);

					string targetRegion = targetFacility[0].ToString();
					string targetDistrict = targetFacility[1].ToString();
					string targetFacilityName = targetFacility[2].ToString();

					foreach (DataSet facilityDataSet in facilitiesDataSet)
					{
						DataTable facilityInfo = facilityDataSet.Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
						DataRow r = facilityInfo.Rows[0];
						string name = r[FACILITY_NAME].ToString();
						string district = r[DISTRICT_NAME].ToString();
						string region = r[REGION_NAME].ToString();

						//if (district == "Lushoto")
						//{
						//    DataTable anc = facilityDataSet.Tables[ExcelTemplateReport.ANC_TABLE];
						//    DataRow anc04Row = anc.Rows[0];
						//    DataRow anc08Row = anc.Rows[1];
						//    int anc04 = 0;
						//    int anc08 = 0;
						//    Int32.TryParse(anc04Row[0].ToString(), out anc04);
						//    Int32.TryParse(anc08Row[0].ToString(), out anc08);
						//    if (anc08 < anc04) anc08Row[0] = anc04;
						//}

						if ((name == targetFacilityName) && (region == targetRegion))
						{
							//string code = r["FACCODE"].ToString();
							bool provideDBS = Boolean.Parse(r[PROVIDEDBS].ToString());
							if (provideDBS)
							{
								//r[PMTCTSITE] = 1;
								r[PMTCTSITE] = TRUE;
								string type = r[FACILITY_TYPE].ToString();
								int iType = Int32.Parse(type);
								//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
								//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
								//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

								if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
								if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
								if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
							}
							else // finding DBS using another means i.e. MAT08 > 0
							{
								try
								{
									DataTable mat = facilityDataSet.Tables[ExcelTemplateReport.MAT_TABLE];
									DataRow mat08Row = mat.Rows[7];
									string key = mat08Row[0].ToString();
									string value = mat08Row[1].ToString();
									if (key == "MAT08")
									{
										int iValue = Int32.Parse(value);
										if (iValue > 0)
										{
											r[PROVIDEDBS] = true;
											string type = r[FACILITY_TYPE].ToString();
											int iType = Int32.Parse(type);
											//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
											//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
											//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

											if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
											if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
											if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
										}
									}
								}
								catch { }
							}

							TangaReportTemplate.DataSource = facilityDataSet;
							TangaReportTemplate.SimplifyDatasetFormat(true);

							// Adding data from baseline sheets
							if (sapr_useBaselineData)
							{
								Dictionary<int, int> dIndex2 = new Dictionary<int, int>();
								foreach (DataRow x in indexSAPRTanga.Rows)
								{
									string xName = x[FACILITY_NAME].ToString();
									string xDistrict = x[DISTRICT_NAME].ToString();
									string xRegion = x[REGION_NAME].ToString();
									if ((xName == targetFacilityName) && (xRegion == targetRegion))
									{
										int startingColumn = 3;
										for (int y = startingColumn; y < indexSAPRTanga.Columns.Count; y++)
										{
											string sColumnName = indexSAPRTanga.Columns[y].ColumnName;
											int iColumnName = Int32.Parse(sColumnName);
											dIndex2[iColumnName] = Int32.Parse(x[sColumnName].ToString());
										}
										indexSAPRTanga.Rows.Remove(x);
										break;
									}
								}

								foreach (var z in TangaReportTemplate.Sheets)
								{
									z.AddValueToCells(dIndex2);
									if (sapr_useMaximumValues)
									{
										foreach (var c in z.Cells)
										{
											int _6monthsValue = 0;
											int _12mothsValue = 0;
											int _6monthsValueSAPR = 0;
											bool isNumerical = false;
											isNumerical = Int32.TryParse(c.Value, out _6monthsValue);
											if (isNumerical)
											{
												_6monthsValue = c.GetValue(facilityDataSet, ExcelTemplateReport.ANC_TABLE,
													ExcelTemplateReport.PCR_TABLE, ExcelTemplateReport.MAT_TABLE, ExcelTemplateReport.MC_TABLE);
												_12mothsValue = c.GetValue(facilityDataSet, MAX_ANC, MAX_PCR, MAX_MAT, MAX_MC);
												_6monthsValueSAPR = Int32.Parse(c.Value);

												if (_12mothsValue > _6monthsValueSAPR)
												{
													int extraValue = _12mothsValue - _6monthsValueSAPR;
													int newValue = Int32.Parse(c.Value) + extraValue;
													c.Value = newValue.ToString();
												}
											}
										}
									}
								}
							}
							TangaReportTemplate.WriteDataToExcelSheet(excelWorksheet, INDICATOR_DATA_ENTRY, columnOffset, rowOffset, false);
							facilitiesDataSet.Remove(facilityDataSet);  //To reduce looping already processed data
							break;
						}
					}

					rowOffset++;
					//excelWorkbook.Save();
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
				}
				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorkbook.Close(true, misValue, misValue);
				excelWorksheet = null;
				#endregion

				#endregion

				#region Processing File - Missing Facilities
				cells = missingReportTemplate.Sheets[0].Cells;
				templatePath = String.Format(@"{0}\Resources\{1}", Application.StartupPath, missingReportTemplate.Filename);
				//System.IO.File.Delete(m_SelectedFilePath);
				destinationFilename = String.Format(@"{0}\{1}", m_SelectedFilePath, missingReportTemplate.Filename);
				System.IO.File.Copy(templatePath, destinationFilename, true);

				excelWorkbook = excelWorkbooks.Open(destinationFilename, 0, false, 5,
					"", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
				currentSheetIndex = 1;
				excelSheets = excelWorkbook.Worksheets;
				excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheetIndex);     // 1-based index

				#region Writing data to excel
				columnOffset = 0;
				rowOffset = 0;
				template = @"Writing to Facility data to Excel Sheet [{0} of {1}]";
				facilityIndex = 0;
				facilityCount = facilitiesDataSet.Count;

				progress = 0;
				progressInfo.minValue = 0;
				progressInfo.maxValue = facilityCount;

				foreach (DataSet facilityDataSet in facilitiesDataSet)
				{
					facilityIndex++;
					progressInfo.log = String.Format(template, facilityIndex, facilityCount);
					progressInfo.value = facilityIndex;
					backgroundWorker.ReportProgress(facilityIndex, progressInfo);

					DataTable facilityInfo = facilityDataSet.Tables[ExcelTemplateReport.FACILITY_INFO_TABLE];
					DataRow r = facilityInfo.Rows[0];
					string name = r[FACILITY_NAME].ToString();
					string district = r[DISTRICT_NAME].ToString();
					string region = r[REGION_NAME].ToString();

					bool provideDBS = false;
					Boolean.TryParse(r[PROVIDEDBS].ToString(), out provideDBS);
					if (provideDBS)
					{
						//r[PMTCTSITE] = 1;
						r[PMTCTSITE] = TRUE;
						string type = r[FACILITY_TYPE].ToString();
						int iType = FACILITY_TYPE_DISPENSARY;
						Int32.TryParse(type, out iType);
						//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
						//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
						//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

						if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
						if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
						if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
					}
					else // finding DBS using another means i.e. MAT08 > 0
					{
						try
						{
							DataTable mat = facilityDataSet.Tables[ExcelTemplateReport.MAT_TABLE];
							DataRow mat08Row = mat.Rows[7];
							string key = mat08Row[0].ToString();
							string value = mat08Row[1].ToString();
							if (key == "MAT08")
							{
								int iValue = 0;
								Int32.TryParse(value, out iValue);
								if (iValue > 0)
								{
									r[PROVIDEDBS] = true;
									string type = r[FACILITY_TYPE].ToString();
									int iType = FACILITY_TYPE_DISPENSARY;
									Int32.TryParse(type, out iType);
									//if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = 1;
									//if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = 1;
									//if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = 1;

									if (iType == FACILITY_TYPE_DISPENSARY) r[DISPENSARY] = TRUE;
									if (iType == FACILITY_TYPE_HEALTH_CENTRE) r[HEALTH_CENTRE] = TRUE;
									if (iType == FACILITY_TYPE_HOSPITAL) r[HOSPITAL] = TRUE;
								}
							}
						}
						catch { }
					}

					missingReportTemplate.DataSource = facilityDataSet;
					missingReportTemplate.WriteDataToExcelSheet(excelWorksheet, MISSING_FACILITIES, columnOffset, rowOffset);
					rowOffset++;
					//excelWorkbook.Save();
					if (backgroundWorker.CancellationPending)
					{
						excelWorkbook.Close(true, misValue, misValue);
						excelApplication.Quit();

						ReleaseObject(excelWorksheet);
						ReleaseObject(excelSheets);
						ReleaseObject(excelWorkbook);
						ReleaseObject(excelWorkbooks);
						ReleaseObject(excelApplication);
						operationCanceled = true;
						return false;
					}
				}

				System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
				excelWorkbook.Close(true, misValue, misValue);
				excelWorksheet = null;
				#endregion

				#endregion

				#region Closing and Cleaning Up
				progress = -1;
				progressInfo.log = "Closing Excel and releasing resources. Please wait...";
				backgroundWorker.ReportProgress(progress, progressInfo);
				excelApplication.Quit();

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				progress = 100;
				progressInfo.log = "Ready";
				progressInfo.minValue = 0;
				progressInfo.maxValue = 100;
				progressInfo.value = 100;
				backgroundWorker.ReportProgress(progress, progressInfo);
				#endregion
				return true;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, AppConfiguration.ApplicationName,
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				try
				{
					excelWorkbook.Close(true, misValue, misValue);
				}
				catch { }
				try
				{
					excelApplication.Quit();
				}
				catch { }

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);

				progress = -1;
				SAPRProgress progressInfo = new SAPRProgress();
				progressInfo.minValue = 0;
				progressInfo.maxValue = 100;
				progressInfo.log = "Error occured while trying to generate report";
				backgroundWorker.ReportProgress(progress, progressInfo);
				return false;
			}
			finally
			{
				if (excelWorkbook != null)
				{
					try
					{
						excelWorkbook.Close(true, misValue, misValue);
					}
					catch { }
					try
					{
						excelApplication.Quit();
					}
					catch { }
				}

				ReleaseObject(excelWorksheet);
				ReleaseObject(excelSheets);
				ReleaseObject(excelWorkbook);
				ReleaseObject(excelWorkbooks);
				ReleaseObject(excelApplication);
			}
		}

        private void btnGeneratePMTCTMonthlyReport_Click2(object sender, EventArgs e)
        {
            string existingFilter = saveFileDialog.Filter;
            saveFileDialog.Filter = "Excel Workbook|*.xlsx";
            DialogResult response = saveFileDialog.ShowDialog(this);
            saveFileDialog.Filter = existingFilter;

            if (response == System.Windows.Forms.DialogResult.OK)
            {
                m_SelectedFilePath = saveFileDialog.FileName;
                generatingPMTCT = true;
                pmtct_startYear = Int32.Parse(cboStartYear.Text);
                pmtct_startPeriod = Int32.Parse(cboStartPeriod.Text);
                pmtct_endYear = Int32.Parse(cboEndYear.Text);
                pmtct_endPeriod = Int32.Parse(cboEndPeriod.Text);

                pmtct_districtsSelected = rdoDistrict.Checked;
                pmtct_regionsSelected = rdoRegion.Checked;
                pmtct_nationSelected = rdoNation.Checked;

                pmtct_districtID = pmtct_regionID = Int32.Parse(cboAggregation.SelectedValue.ToString());

                groupBox8.Enabled = false;
                cboAggregation.Enabled = false;
                cboStartYear.Enabled = false;
                cboStartPeriod.Enabled = false;

                cboEndYear.Enabled = false;
                cboEndPeriod.Enabled = false;

                btnGenerateDonorReport.Enabled = false;
                btnGenerateSAPR.Enabled = false;
                btnGeneratePMTCTMonthlyReport.Enabled = false;
                btnGenerateSAPRPromise.Enabled = false;

                lblProgress.Visible = true;
                progressBar.Visible = true;
                btnCancel.Visible = true;

                if (backgroundWorker != null) backgroundWorker.Dispose();
                backgroundWorker = new BackgroundWorker();
                backgroundWorker.WorkerSupportsCancellation = true;
                backgroundWorker.WorkerReportsProgress = true;

                backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
                backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
                backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

                backgroundWorker.RunWorkerAsync();
            }
        }

		#endregion

		#region Charts Tab Page
		private bool tabPageChartsLoaded = false;
		private const int MAX_CHART_SERIES = 20;

		private void tabPageCharts_Enter(object sender, EventArgs e)
		{
			if (!tabPageChartsLoaded)
			{
				try
				{
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					DataTable dataTable = Utilities.GetAllReportYears();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string year = row["Year"].ToString();
						StartingYearComboBox.Items.Add(year);
						EndingYearComboBox.Items.Add(year);
					}

					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					dataTable = Utilities.GetAllReportPeriods();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";
					foreach (DataRow row in dataTable.Rows)
					{
						string period = row["Period"].ToString();
						StartingPeriodComboBox.Items.Add(period);
						EndingPeriodComboBox.Items.Add(period);
					}
					try
					{
						StartingYearComboBox.SelectedIndex = 0;
						EndingYearComboBox.SelectedIndex = 0;
						StartingPeriodComboBox.SelectedIndex = 0;
						EndingPeriodComboBox.SelectedIndex = 0;
					}
					catch { }

					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					dataTable = Utilities.GetAllExpectedCharts();
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					ReportComboBox.DataSource = dataTable;
					ReportComboBox.DisplayMember = "ChartName";
					ReportComboBox.ValueMember = "ChartID";
					PopulateChartIndicators();

					DataTable regions = null;
					Cursor.Current = Cursors.WaitCursor;
					toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
					switch (this.authenticatedUser.Level)
					{
                        case AccessLevel.FACILITY:
							RegionGroupBox.Enabled = false;
							DistrictGroupBox.Enabled = false;
							FacilityGroupBox.Enabled = false;
							AggregationCheckBox.Enabled = false;
							string facilityCode = this.authenticatedUser.AccessLevelValue;
							regions = Utilities.GetFacilityRegion(facilityCode);
                            PopulateListBox(AvailableRegionsListBox, regions, ReportLevel.REGION);
							BtnAddRegion_Click(null, null);
							BtnAddDistrict_Click(null, null);
							BtnAddFacility_Click(null, null);
							break;

                        case AccessLevel.DISTRICT:
							RegionGroupBox.Enabled = false;
							DistrictGroupBox.Enabled = false;
							AggregationCheckBox.Enabled = false;
							int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							regions = Utilities.GetDistrictRegion(districtID);
                            PopulateListBox(AvailableRegionsListBox, regions, ReportLevel.REGION);
							BtnAddRegion_Click(null, null);
							BtnAddDistrict_Click(null, null);
							break;

                        case AccessLevel.REGION:
							RegionGroupBox.Enabled = false;
							int regionID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
							regions = Utilities.GetRegion(regionID);
                            PopulateListBox(AvailableRegionsListBox, regions, ReportLevel.REGION);
							BtnAddRegion_Click(null, null);
							break;

                        case AccessLevel.NATION:
							regions = Utilities.GetAllRegions(this.authenticatedUser.SupportingPartnerId);
                            PopulateListBox(AvailableRegionsListBox, regions, ReportLevel.REGION);
							break;

                        case AccessLevel.ADMINISTRATOR:
							regions = Utilities.GetAllRegions();
                            PopulateListBox(AvailableRegionsListBox, regions, ReportLevel.REGION);
							break;
					}
					Cursor.Current = Cursors.Default;
					toolStripStatusLabel.Text = "Ready";

					UpdateRegionButtons();
					UpdateDistrictButtons();
					UpdateFacilityButtons();

					tabPageChartsLoaded = true;
				}
				catch (Exception ex)
				{
					DisplayErrorMessage(ex);
				}
			}
		}

		#region Private Helper Methods
		/// <summary>
		/// Add an item from listbox source to listbox destination
		/// </summary>
		/// <param name="source">Source of the item</param>
		/// <param name="destination">Destination of the item</param>
		private void AddListItem(ListBox source, ListBox destination)
		{
			ListBoxItem selectedItem = (ListBoxItem)source.SelectedItem;
			int selectedIndex = source.SelectedIndex;
			source.Items.RemoveAt(selectedIndex);

			if (source.Items.Count > 0)
			{
				if (selectedIndex != 0) selectedIndex--;
				source.SelectedIndex = selectedIndex;
			}

			destination.Items.Add(selectedItem);
			destination.SelectedIndex = destination.Items.Count - 1;
		}

        private void PopulateListBox(ListBox listBox, DataTable dataTable, ReportLevel level)
		{
			listBox.SuspendLayout();
			switch (level)
			{
				case ReportLevel.REGION:
					foreach (DataRow row in dataTable.Rows)
					{
						int regionID = int.Parse(row["RegionID"].ToString());
						string displayText = row["RegionName"].ToString();
						ListBoxItem listBoxItem = new ListBoxItem(displayText, regionID);
						listBox.Items.Add(listBoxItem);
					}
					break;

                case ReportLevel.DISTRICT:
					foreach (DataRow row in dataTable.Rows)
					{
						int regionID = int.Parse(row["RegionID"].ToString());
						int districtID = int.Parse(row["DistrictID"].ToString());
						string displayText = row["DistrictName"].ToString();
						ListBoxItem listBoxItem = new ListBoxItem(displayText, regionID, districtID);
						listBox.Items.Add(listBoxItem);
					}
					break;

                case ReportLevel.FACILITY:
					foreach (DataRow row in dataTable.Rows)
					{
						int regionID = int.Parse(row["RegionID"].ToString());
						int districtID = int.Parse(row["DistrictID"].ToString());
						string facilityCode = row["FacilityCode"].ToString();
						string displayText = row["FacilityName"].ToString();
						ListBoxItem listBoxItem = new ListBoxItem(displayText, regionID, districtID, facilityCode);
						listBox.Items.Add(listBoxItem);
					}
					break;
			}

			listBox.ResumeLayout();
		}

		public void AddDistricts(int regionID)
		{
			DataTable districts = null;
			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			switch (this.authenticatedUser.Level)
			{
                case AccessLevel.ADMINISTRATOR:
					districts = Utilities.GetDistrictsByRegion(regionID);
					break;

                case AccessLevel.NATION:
                case AccessLevel.REGION:
					districts = Utilities.GetDistrictsByRegion(regionID, this.authenticatedUser.SupportingPartnerId);
					break;

                case AccessLevel.DISTRICT:
					int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
					districts = Utilities.GetDistrict(districtID);
					break;

                case AccessLevel.FACILITY:
					string facilityCode = this.authenticatedUser.AccessLevelValue;
					districts = Utilities.GetFacilityDistrict(facilityCode);
					break;
			}
			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			foreach (DataRow row in districts.Rows)
			{
				string displayText = row["District"].ToString();
				int districtID = int.Parse(row["DistrictNo"].ToString());
				ListBoxItem item = new ListBoxItem(displayText, regionID, districtID);
				AvailableDistrictsListBox.Items.Add(item);
			}
			UpdateDistrictButtons();
		}

		public void AddFacilities(int districtID)
		{
			DataTable facilities = null;
			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			switch (this.authenticatedUser.Level)
			{
                case AccessLevel.ADMINISTRATOR:
					facilities = Utilities.GetFacilitiesDetailsByDistrict(districtID);
					break;

                case AccessLevel.NATION:
                case AccessLevel.REGION:
					facilities = Utilities.GetFacilitiesDetailsByDistrict(districtID, this.authenticatedUser.SupportingPartnerId);
					break;

                case AccessLevel.DISTRICT:
					facilities = Utilities.GetFacilitiesDetailsByDistrict(districtID);
					break;

                case AccessLevel.FACILITY:
					string facilityCode = this.authenticatedUser.AccessLevelValue;
					facilities = Utilities.GetFacilityDetails(facilityCode);
					break;
			}
			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			foreach (DataRow row in facilities.Rows)
			{
				string displayText = row["FacName"].ToString();
				int regionID = int.Parse(row["Region"].ToString());
				string facilityCode = row["FacCode"].ToString();
				ListBoxItem item = new ListBoxItem(displayText, regionID, districtID, facilityCode);
				AvailableFacilitiesListBox.Items.Add(item);
			}
			UpdateFacilityButtons();
		}

		public void RemoveDistricts(int regionID)
		{
			List<ListBoxItem> itemsToDelete = new List<ListBoxItem>();
			// Remove districts in the available list
			foreach (ListBoxItem listBoxItem in AvailableDistrictsListBox.Items)
			{
				if (regionID == listBoxItem.RegionID) itemsToDelete.Add(listBoxItem);
			}
			foreach (ListBoxItem x in itemsToDelete) AvailableDistrictsListBox.Items.Remove(x);
			itemsToDelete.Clear();
			// Remove districts in the selected list
			foreach (ListBoxItem listBoxItem in SelectedDistrictsListBox.Items)
			{
				if (regionID == listBoxItem.RegionID) itemsToDelete.Add(listBoxItem);
			}
			foreach (ListBoxItem x in itemsToDelete)
			{
				SelectedDistrictsListBox.Items.Remove(x);
				RemoveFacilities(x.DistrictID);
			}
			UpdateDistrictButtons();
		}

		public void RemoveFacilities(int districtID)
		{
			List<ListBoxItem> itemsToDelete = new List<ListBoxItem>();
			// Remove facilities in the available list
			foreach (ListBoxItem listBoxItem in AvailableFacilitiesListBox.Items)
			{
				if (districtID == listBoxItem.DistrictID) itemsToDelete.Add(listBoxItem);
			}
			foreach (ListBoxItem x in itemsToDelete) AvailableFacilitiesListBox.Items.Remove(x);
			itemsToDelete.Clear();
			// Remove facilities in the selected list
			foreach (ListBoxItem listBoxItem in SelectedFacilitiesListBox.Items)
			{
				if (districtID == listBoxItem.DistrictID) itemsToDelete.Add(listBoxItem);
			}
			foreach (ListBoxItem x in itemsToDelete) SelectedFacilitiesListBox.Items.Remove(x);
			UpdateFacilityButtons();
		}

		private void AddAllListItems(ListBox source, ListBox destination)
		{
			source.SuspendLayout();
			destination.SuspendLayout();
			foreach (object item in source.Items)
			{
				ListBoxItem listBoxItem = (ListBoxItem)item;
				destination.Items.Add(listBoxItem);
			}
			source.Items.Clear();
			destination.SelectedIndex = destination.Items.Count - 1;

			destination.ResumeLayout();
			source.ResumeLayout();
		}

		#region Transferring Buttons Management
		private void UpdateRegionButtons()
		{
			int selectedRegions = SelectedRegionsListBox.Items.Count;
			int availableRegions = AvailableRegionsListBox.Items.Count;

			// We enable only if there are regions to add
			BtnAddRegion.Enabled = (availableRegions > 0);
			BtnAddAllRegions.Enabled = (availableRegions > 0);

			// We enable only if there are regions to remove
			BtnRemoveRegion.Enabled = (selectedRegions > 0);
			BtnRemoveAllRegions.Enabled = (selectedRegions > 0);
		}

		private void UpdateDistrictButtons()
		{
			int selectedDistricts = SelectedDistrictsListBox.Items.Count;
			int availableDistricts = AvailableDistrictsListBox.Items.Count;

			// We enable only if there are districts to add
			BtnAddDistrict.Enabled = (availableDistricts > 0);
			BtnAddAllDistricts.Enabled = (availableDistricts > 0);

			// We enable only if there are districts to remove
			BtnRemoveDistrict.Enabled = (selectedDistricts > 0);
			BtnRemoveAllDistricts.Enabled = (selectedDistricts > 0);
		}

		private void UpdateFacilityButtons()
		{
			int selectedFacilities = SelectedFacilitiesListBox.Items.Count;
			int availableFacilities = AvailableFacilitiesListBox.Items.Count;

			// We enable only if there are districts to add
			BtnAddFacility.Enabled = (availableFacilities > 0);
			BtnAddAllFacilities.Enabled = (availableFacilities > 0);

			// We enable only if there are districts to remove
			BtnRemoveFacility.Enabled = (selectedFacilities > 0);
			BtnRemoveAllFacilities.Enabled = (selectedFacilities > 0);
		}
		#endregion

		private bool ValidateTimeFrame()
		{
			bool okToContinue = false;
			int endingYear = int.Parse(EndingYearComboBox.Text);
			int startingYear = int.Parse(StartingYearComboBox.Text);
			int endingPeriod = int.Parse(EndingPeriodComboBox.Text);
			int startingPeriod = int.Parse(StartingPeriodComboBox.Text);

			if (endingYear > startingYear) okToContinue = true;
			else
			{
				if (endingYear < startingYear) okToContinue = false;
				else
				{
					if (endingPeriod >= startingPeriod) okToContinue = true;
					else okToContinue = false;
				}
			}
			return okToContinue;
		}

		private void PopulateChartIndicators()
		{
			int chartID = Int32.Parse(ReportComboBox.SelectedValue.ToString());

			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			DataTable dataTable = Utilities.GetChartIndicators(chartID);
			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			ReportIndicatorsCheckedListBox.Items.Clear();
			foreach (DataRow row in dataTable.Rows)
			{
				ChartIndicatorInfo indicatorInfo = new ChartIndicatorInfo();
				indicatorInfo.ChartID = int.Parse(row["ChartID"].ToString());
				indicatorInfo.IndicatorID = int.Parse(row["IndicatorID"].ToString());
				indicatorInfo.IndicatorName = row["IndicatorName"].ToString();
				indicatorInfo.IndicatorDefinition = row["IndicatorDefinition"].ToString();
				indicatorInfo.IsComposite = bool.Parse(row["CompositeIndicator"].ToString());

				ListItem item = new ListItem();
				item.Text = indicatorInfo.IndicatorName;
				item.Value = indicatorInfo;

				ReportIndicatorsCheckedListBox.Items.Add(item);
			}
		}

		private string GetTimeFrameDescription()
		{
			return String.Format("{0} {1} - {2} {3}",
				Utilities.GetMonthText(int.Parse(StartingPeriodComboBox.Text), true), int.Parse(StartingYearComboBox.Text),
				Utilities.GetMonthText(int.Parse(EndingPeriodComboBox.Text), true), int.Parse(EndingYearComboBox.Text));
		}

		private DataSet GetRegionsChartDataSet()
		{
			int chartID = int.Parse(ReportComboBox.SelectedValue.ToString());
			int suffix = 0;
			DataSet dataset = new DataSet();
			foreach (ListBoxItem listBoxItem in SelectedRegionsListBox.Items)
			{
				int regionID = listBoxItem.RegionID;
				string regionName = listBoxItem.Text;
				DataTable dataTable = GetChartData(ReportLevel.REGION, regionID);

				dataTable.TableName = regionName;
				try
				{
					dataset.Tables.Add(dataTable);
				}
				catch (DuplicateNameException ex)
				{
					dataTable.TableName = regionID + "_" + 0;
					suffix++;
					dataset.Tables.Add(dataTable);
				}
			}
			return dataset;
		}

		private DataSet GetDistrictsChartDataSet()
		{
			int chartID = int.Parse(ReportComboBox.SelectedValue.ToString());
			int suffix = 0;
			DataSet dataset = new DataSet();
			foreach (ListBoxItem listBoxItem in SelectedDistrictsListBox.Items)
			{
				int districtID = listBoxItem.DistrictID;
				string districtName = listBoxItem.Text;
				DataTable dataTable = GetChartData(ReportLevel.DISTRICT, districtID);

				dataTable.TableName = districtName;
				try
				{
					dataset.Tables.Add(dataTable);
				}
				catch (DuplicateNameException ex)
				{
					dataTable.TableName = districtID + "_" + 0;
					suffix++;
					dataset.Tables.Add(dataTable);
				}
			}
			return dataset;
		}

		private DataSet GetFacilitiesChartDataSet()
		{
			int chartID = int.Parse(ReportComboBox.SelectedValue.ToString());
			int suffix = 0;
			DataSet dataset = new DataSet();
			foreach (ListBoxItem listBoxItem in SelectedFacilitiesListBox.Items)
			{
				string facilityCode = listBoxItem.FacilityCode;
				string facilityName = listBoxItem.Text;
                DataTable dataTable = GetChartData(ReportLevel.FACILITY, facilityCode);

				dataTable.TableName = facilityName;
				try
				{
					dataset.Tables.Add(dataTable);
				}
				catch (DuplicateNameException ex)
				{
					dataTable.TableName = facilityCode + "_" + 0;
					suffix++;
					dataset.Tables.Add(dataTable);
				}
			}
			return dataset;
		}

		private DataTable GetChartData(ReportLevel level, object levelID)
		{
			int startYear = Int32.Parse(StartingYearComboBox.Text);
			int startPeriod = Int32.Parse(StartingPeriodComboBox.Text);
			int endYear = Int32.Parse(EndingYearComboBox.Text);
			int endPeriod = Int32.Parse(EndingPeriodComboBox.Text);
            List<ChartIndicatorInfo> reportIndicators = new List<ChartIndicatorInfo>();
			foreach (ListItem item in ReportIndicatorsCheckedListBox.CheckedItems)
			{
                ChartIndicatorInfo indicator = (ChartIndicatorInfo)item.Value;
				reportIndicators.Add(indicator);
			}

			Cursor.Current = Cursors.WaitCursor;
			toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
			DataTable dataTable = Utilities.GetChartData(level, levelID, startYear, startPeriod,
				endYear, endPeriod, reportIndicators);
			Cursor.Current = Cursors.Default;
			toolStripStatusLabel.Text = "Ready";

			return dataTable;
		}
		#endregion

		#region Event Handlers
		private void ReportComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			try
			{
				PopulateChartIndicators();
			}
			catch (Exception ex)
			{
				if (tabPageChartsLoaded) DisplayErrorMessage(ex);
			}
		}

		private void AggregationCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (AggregationCheckBox.Checked)
			{
				switch (this.authenticatedUser.Level)
				{
                    case AccessLevel.ADMINISTRATOR:
                    case AccessLevel.NATION:
						rdoRegions.Enabled = true;
						rdoDistricts.Enabled = true;
						break;

                    case AccessLevel.REGION:
						rdoDistricts.Enabled = true;
						break;
				}
			}
			else
			{
				switch (this.authenticatedUser.Level)
				{
                    case AccessLevel.ADMINISTRATOR:
                    case AccessLevel.NATION:
						RegionGroupBox.Enabled = true;
						DistrictGroupBox.Enabled = true;
						FacilityGroupBox.Enabled = true;
						break;

                    case AccessLevel.REGION:
						DistrictGroupBox.Enabled = true;
						FacilityGroupBox.Enabled = true;
						break;

                    case AccessLevel.DISTRICT:
						FacilityGroupBox.Enabled = true;
						break;
				}
				rdoRegions.Enabled = false;
				rdoDistricts.Enabled = false;
			}
		}

		private void AvailableRegionsListBox_DoubleClick(object sender, EventArgs e)
		{
			if (AvailableRegionsListBox.Items.Count > 0) BtnAddRegion_Click(null, null);
		}

		private void SelectedRegionsListBox_DoubleClick(object sender, EventArgs e)
		{
			if (SelectedRegionsListBox.Items.Count > 0) BtnRemoveRegion_Click(null, null);
		}

		private void AvailableDistrictsListBox_DoubleClick(object sender, EventArgs e)
		{
			if (AvailableDistrictsListBox.Items.Count > 0) BtnAddDistrict_Click(null, null);
		}

		private void SelectedDistrictsListBox_DoubleClick(object sender, EventArgs e)
		{
			if (SelectedDistrictsListBox.Items.Count > 0) BtnRemoveDistrict_Click(null, null);
		}

		private void AvailableFacilitiesListBox_DoubleClick(object sender, EventArgs e)
		{
			if (AvailableFacilitiesListBox.Items.Count > 0) BtnAddFacility_Click(null, null);
		}

		private void SelectedFacilitiesListBox_DoubleClick(object sender, EventArgs e)
		{
			if (SelectedFacilitiesListBox.Items.Count > 0) BtnRemoveFacility_Click(null, null);
		}

		private void BtnAddAllRegions_Click(object sender, EventArgs e)
		{
			try
			{
				List<int> existingRegions = new List<int>();
				foreach (ListBoxItem x in SelectedRegionsListBox.Items) existingRegions.Add(x.RegionID);

				AddAllListItems(AvailableRegionsListBox, SelectedRegionsListBox);
				UpdateRegionButtons();

				foreach (ListBoxItem item in SelectedRegionsListBox.Items)
				{
					bool notAdded = true;
					foreach (int y in existingRegions) if (y == item.RegionID) notAdded = false;
					if (notAdded) AddDistricts(item.RegionID);
				}
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnAddRegion_Click(object sender, EventArgs e)
		{
			try
			{
				if (AvailableRegionsListBox.SelectedIndex == -1) AvailableRegionsListBox.SelectedIndex = 0;
				ListBoxItem selectedItem = (ListBoxItem)AvailableRegionsListBox.SelectedItem;
				AddListItem(AvailableRegionsListBox, SelectedRegionsListBox);
				UpdateRegionButtons();
				AddDistricts(selectedItem.RegionID);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveRegion_Click(object sender, EventArgs e)
		{
			try
			{
				if (SelectedRegionsListBox.SelectedIndex == -1) SelectedRegionsListBox.SelectedIndex = 0;
				ListBoxItem selectedItem = (ListBoxItem)SelectedRegionsListBox.SelectedItem;
				AddListItem(SelectedRegionsListBox, AvailableRegionsListBox);
				UpdateRegionButtons();
				RemoveDistricts(selectedItem.RegionID);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveAllRegions_Click(object sender, EventArgs e)
		{
			try
			{
				List<int> existingRegions = new List<int>();
				foreach (ListBoxItem x in AvailableRegionsListBox.Items) existingRegions.Add(x.RegionID);

				AddAllListItems(SelectedRegionsListBox, AvailableRegionsListBox);
				UpdateRegionButtons();

				List<int> regionsToRemove = new List<int>();
				foreach (ListBoxItem item in AvailableRegionsListBox.Items)
				{
					bool notRemoved = true;
					foreach (int y in existingRegions) if (y == item.RegionID) notRemoved = false;
					if (notRemoved) regionsToRemove.Add(item.RegionID);
				}
				foreach (int x in regionsToRemove) RemoveDistricts(x);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnAddAllDistricts_Click(object sender, EventArgs e)
		{
			try
			{
				List<int> existingDistricts = new List<int>();
				foreach (ListBoxItem x in SelectedDistrictsListBox.Items) existingDistricts.Add(x.DistrictID);

				AddAllListItems(AvailableDistrictsListBox, SelectedDistrictsListBox);
				UpdateDistrictButtons();

				foreach (ListBoxItem item in SelectedDistrictsListBox.Items)
				{
					bool notAdded = true;
					foreach (int y in existingDistricts) if (y == item.DistrictID) notAdded = false;
					if (notAdded) AddFacilities(item.DistrictID);
				}
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnAddDistrict_Click(object sender, EventArgs e)
		{
			try
			{
				if (AvailableDistrictsListBox.SelectedIndex == -1) AvailableDistrictsListBox.SelectedIndex = 0;
				ListBoxItem selectedItem = (ListBoxItem)AvailableDistrictsListBox.SelectedItem;
				AddListItem(AvailableDistrictsListBox, SelectedDistrictsListBox);
				UpdateDistrictButtons();
				AddFacilities(selectedItem.DistrictID);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveDistrict_Click(object sender, EventArgs e)
		{
			try
			{
				if (SelectedDistrictsListBox.SelectedIndex == -1) SelectedDistrictsListBox.SelectedIndex = 0;
				ListBoxItem selectedItem = (ListBoxItem)SelectedDistrictsListBox.SelectedItem;
				AddListItem(SelectedDistrictsListBox, AvailableDistrictsListBox);
				UpdateDistrictButtons();
				RemoveFacilities(selectedItem.DistrictID);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveAllDistricts_Click(object sender, EventArgs e)
		{
			try
			{
				List<int> existingDistricts = new List<int>();
				foreach (ListBoxItem x in AvailableDistrictsListBox.Items) existingDistricts.Add(x.DistrictID);

				AddAllListItems(SelectedDistrictsListBox, AvailableDistrictsListBox);
				UpdateDistrictButtons();

				List<int> facilitiesToRemove = new List<int>();
				foreach (ListBoxItem item in AvailableDistrictsListBox.Items)
				{
					bool notRemoved = true;
					foreach (int y in existingDistricts) if (y == item.DistrictID) notRemoved = false;
					if (notRemoved) facilitiesToRemove.Add(item.DistrictID);
				}
				foreach (int x in facilitiesToRemove) RemoveFacilities(x);
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnAddAllFacilities_Click(object sender, EventArgs e)
		{
			try
			{
				AddAllListItems(AvailableFacilitiesListBox, SelectedFacilitiesListBox);
				UpdateFacilityButtons();
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnAddFacility_Click(object sender, EventArgs e)
		{
			try
			{
				if (AvailableFacilitiesListBox.SelectedIndex == -1) AvailableFacilitiesListBox.SelectedIndex = 0;
				AddListItem(AvailableFacilitiesListBox, SelectedFacilitiesListBox);
				UpdateFacilityButtons();
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveFacility_Click(object sender, EventArgs e)
		{
			try
			{
				if (SelectedFacilitiesListBox.SelectedIndex == -1) SelectedFacilitiesListBox.SelectedIndex = 0;
				AddListItem(SelectedFacilitiesListBox, AvailableFacilitiesListBox);
				UpdateFacilityButtons();
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void BtnRemoveAllFacilities_Click(object sender, EventArgs e)
		{
			try
			{
				AddAllListItems(SelectedFacilitiesListBox, AvailableFacilitiesListBox);
				UpdateFacilityButtons();
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
			}
		}

		private void btnGenerateChart_Click(object sender, EventArgs e)
		{
			try
			{
				Cursor.Current = Cursors.WaitCursor;
				btnGenerateChart.Enabled = false;
				toolStripStatusLabel.Text = "Loading data, please wait...";
				Application.DoEvents();

				if (ReportIndicatorsCheckedListBox.CheckedItems.Count < 1)
				{
					MessageBox.Show(this, "Please select at least one report indicator",
						"Error - Empty Selection", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					btnGenerateChart.Enabled = true;
					return;
				}

				bool okToContinue = ValidateTimeFrame();
				if (okToContinue)
				{
					if (AggregationCheckBox.Checked)
					{
						#region Aggregation Selected
						#region Region Aggregation
						if (rdoRegions.Checked)
						{
							if (SelectedRegionsListBox.Items.Count > 0)
							{
								if (SelectedRegionsListBox.Items.Count > MAX_CHART_SERIES)
								{
									MessageBox.Show(this, String.Format("You have exceeded the allowed chart items. Please reduce the number of items\n\nMaximum allowed items is {0} items",
										MAX_CHART_SERIES), "Items Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
									btnGenerateChart.Enabled = true;
									return;
								}
								//DataSet dataset = GetRegionsReportDataSet();
								DataSet dataset = GetRegionsChartDataSet();
								Dictionary<string, string> reportParameters = new Dictionary<string, string>();

								reportParameters.Add("Title", ReportComboBox.Text);
								reportParameters.Add("TimeFrame", GetTimeFrameDescription());
								Chart chart = new Chart(dataset, reportParameters);
                                chart.Show(this);
							}
							else
							{
								MessageBox.Show(this, "Please select at least one region",
										"Error - Empty Selection", MessageBoxButtons.OK, MessageBoxIcon.Stop);
							}
						}
						#endregion

						#region District Aggregation
						if (rdoDistricts.Checked)
						{
							if (SelectedDistrictsListBox.Items.Count > 0)
							{
								if (SelectedDistrictsListBox.Items.Count > MAX_CHART_SERIES)
								{
									MessageBox.Show(this, String.Format("You have exceeded the allowed chart items. Please reduce the number of items\n\nMaximum allowed items is {0} items",
										MAX_CHART_SERIES), "Items Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
									btnGenerateChart.Enabled = true;
									return;
								}
								//DataSet dataset = GetDistrictsReportDataSet();
								DataSet dataset = GetDistrictsChartDataSet();
								Dictionary<string, string> reportParameters = new Dictionary<string, string>();

								reportParameters.Add("Title", ReportComboBox.Text);
								reportParameters.Add("TimeFrame", GetTimeFrameDescription());
                                Chart chart = new Chart(dataset, reportParameters);
                                chart.Show(this);
							}
							else
							{
								MessageBox.Show(this, "Please select at least one district",
										"Error - Empty Selection", MessageBoxButtons.OK, MessageBoxIcon.Stop);
							}
						}
						#endregion
						#endregion
					}
					else
					{
						#region Something Else but Aggregation
						// Check if the facilities are selected.
						if (SelectedFacilitiesListBox.Items.Count > 0)
						{
							#region Facilities
							if (SelectedFacilitiesListBox.Items.Count > MAX_CHART_SERIES)
							{
								MessageBox.Show(this, String.Format("You have exceeded the allowed chart items. Please reduce the number of items\n\nMaximum allowed items is {0} items",
									MAX_CHART_SERIES), "Items Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
								btnGenerateChart.Enabled = true;
								return;
							}
							//DataSet dataset = GetFacilitiesReportDataSet();
							DataSet dataset = GetFacilitiesChartDataSet();
							Dictionary<string, string> reportParameters = new Dictionary<string, string>();

							reportParameters.Add("Title", ReportComboBox.Text);
							reportParameters.Add("TimeFrame", GetTimeFrameDescription());
                            Chart chart = new Chart(dataset, reportParameters);
                            chart.Show(this);
							#endregion
						}
						else
						{
							if (SelectedDistrictsListBox.Items.Count > 0)
							{
								#region Districts
								if (SelectedDistrictsListBox.Items.Count > MAX_CHART_SERIES)
								{
									MessageBox.Show(this, String.Format("You have exceeded the allowed chart items. Please reduce the number of items\n\nMaximum allowed items is {0} items",
										MAX_CHART_SERIES), "Items Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
									btnGenerateChart.Enabled = true;
									return;
								}

								//DataSet dataset = GetDistrictsReportDataSet();
								DataSet dataset = GetDistrictsChartDataSet();
								Dictionary<string, string> reportParameters = new Dictionary<string, string>();

								reportParameters.Add("Title", ReportComboBox.Text);
								reportParameters.Add("TimeFrame", GetTimeFrameDescription());
                                Chart chart = new Chart(dataset, reportParameters);
                                chart.Show(this);
								#endregion
							}
							else
							{
								#region Regions
								if (SelectedRegionsListBox.Items.Count > 0)
								{
									if (SelectedRegionsListBox.Items.Count > MAX_CHART_SERIES)
									{
										MessageBox.Show(this, String.Format("You have exceeded the allowed chart items. Please reduce the number of items\n\nMaximum allowed items is {0} items",
											MAX_CHART_SERIES), "Items Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
										btnGenerateChart.Enabled = true;
										return;
									}

									//DataSet dataset = GetRegionsReportDataSet();
									DataSet dataset = GetRegionsChartDataSet();
									Dictionary<string, string> reportParameters = new Dictionary<string, string>();

									reportParameters.Add("Title", ReportComboBox.Text);
									reportParameters.Add("TimeFrame", GetTimeFrameDescription());
                                    Chart chart = new Chart(dataset, reportParameters);
                                    chart.Show(this);
								}
								#endregion
								else
								{
									MessageBox.Show(this, "Please select at least one region, district or facility",
										"Error - Empty Selection", MessageBoxButtons.OK, MessageBoxIcon.Stop);
								}
							}
						}
						#endregion
					}
				}
				else
				{
					MessageBox.Show(this, "Please make sure the time frame is correct\n\nStarting time should be older than Ending time",
						"Time Frame Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
					btnGenerateChart.Enabled = true;
					return;
				}

				btnGenerateChart.Enabled = true;
				toolStripStatusLabel.Text = "Ready";
				Cursor.Current = Cursors.Default;
			}
			catch (Exception ex)
			{
				DisplayErrorMessage(ex);
				btnGenerateChart.Enabled = true;
			}
		}

		private void rdoRegions_CheckedChanged(object sender, EventArgs e)
		{
			if (rdoRegions.Checked)
			{
				RegionGroupBox.Enabled = true;
				DistrictGroupBox.Enabled = false;
				FacilityGroupBox.Enabled = false;
			}
		}

		private void rdoDistricts_CheckedChanged(object sender, EventArgs e)
		{
			if (rdoDistricts.Checked)
			{
				RegionGroupBox.Enabled = true;
				DistrictGroupBox.Enabled = true;
				FacilityGroupBox.Enabled = false;
			}
		}
		#endregion
		#endregion


        bool tabPageReadOnlyMTUHALoaded = false;
        private void tabPageReadOnlyMTUHA_Enter(object sender, EventArgs e)
        {
            if (!tabPageReadOnlyMTUHALoaded)
            {
                try
                {
                    this.Cursor = Cursors.WaitCursor;
                    var mtuhaTabs = elementHost1.Child as MTUHAReportsTab;
                    if (mtuhaTabs != null)
                    {
                        var ancForm = mtuhaTabs.FindName("ancForm") as ANCMTUHAReport;
                        var ldForm = mtuhaTabs.FindName("ldForm") as LDMTUHAReport;
                        if (ancForm != null)
                        {
                            ancForm.User = this.authenticatedUser;
                            ancForm.Mode = ANCMTUHAReport.ViewMode.READ_ONLY;
                            var grid = ancForm.FindName("gridActionPanel") as System.Windows.Controls.Grid;
                            grid.Visibility = System.Windows.Visibility.Collapsed;
                        }

                        if (ldForm != null)
                        {
                            ldForm.User = this.authenticatedUser;
                            ldForm.Mode = LDMTUHAReport.ViewMode.READ_ONLY;
                            var grid = ldForm.FindName("gridActionPanel") as System.Windows.Controls.Grid;
                            grid.Visibility = System.Windows.Visibility.Collapsed;
                        }
                    }
                    tabPageReadOnlyMTUHALoaded = true;
                }
                catch (Exception ex)
                {
                    DisplayErrorMessage(ex);
                }
                finally
                {
                    this.Cursor = Cursors.Default;
                }
            }
        }
	}
}